[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 1 | // Copyright 2013 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 NET_DNS_MDNS_CLIENT_H_ |
| 6 | #define NET_DNS_MDNS_CLIENT_H_ |
| 7 | |
Avi Drissman | 13fc893 | 2015-12-20 04:40:46 | [diff] [blame] | 8 | #include <stdint.h> |
| 9 | |
danakj | 22f90e7 | 2016-04-16 01:55:40 | [diff] [blame] | 10 | #include <memory> |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 11 | #include <string> |
| 12 | #include <vector> |
| 13 | |
| 14 | #include "base/callback.h" |
[email protected] | 7604fa22 | 2013-09-19 06:07:04 | [diff] [blame] | 15 | #include "net/base/ip_endpoint.h" |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 16 | #include "net/dns/dns_query.h" |
| 17 | #include "net/dns/dns_response.h" |
| 18 | #include "net/dns/record_parsed.h" |
| 19 | |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 20 | namespace net { |
| 21 | |
[email protected] | 95b331b4 | 2013-12-02 06:26:31 | [diff] [blame] | 22 | class DatagramServerSocket; |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 23 | class RecordParsed; |
| 24 | |
| 25 | // Represents a one-time record lookup. A transaction takes one |
| 26 | // associated callback (see |MDnsClient::CreateTransaction|) and calls it |
| 27 | // whenever a matching record has been found, either from the cache or |
| 28 | // by querying the network (it may choose to query either or both based on its |
| 29 | // creation flags, see MDnsTransactionFlags). Network-based transactions will |
| 30 | // time out after a reasonable number of seconds. |
[email protected] | 2ef49b3 | 2013-06-20 20:17:09 | [diff] [blame] | 31 | class NET_EXPORT MDnsTransaction { |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 32 | public: |
[email protected] | 31b487c5 | 2014-05-04 18:49:29 | [diff] [blame] | 33 | // Used to signify what type of result the transaction has received. |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 34 | enum Result { |
| 35 | // Passed whenever a record is found. |
| 36 | RESULT_RECORD, |
| 37 | // The transaction is done. Applies to non-single-valued transactions. Is |
| 38 | // called when the transaction has finished (this is the last call to the |
| 39 | // callback). |
| 40 | RESULT_DONE, |
| 41 | // No results have been found. Applies to single-valued transactions. Is |
| 42 | // called when the transaction has finished without finding any results. |
| 43 | // For transactions that use the network, this happens when a timeout |
| 44 | // occurs, for transactions that are cache-only, this happens when no |
| 45 | // results are in the cache. |
| 46 | RESULT_NO_RESULTS, |
| 47 | // Called when an NSec record is read for this transaction's |
| 48 | // query. This means there cannot possibly be a record of the type |
| 49 | // and name for this transaction. |
| 50 | RESULT_NSEC |
| 51 | }; |
| 52 | |
| 53 | // Used when creating an MDnsTransaction. |
| 54 | enum Flags { |
| 55 | // Transaction should return only one result, and stop listening after it. |
| 56 | // Note that single result transactions will signal when their timeout is |
| 57 | // reached, whereas multi-result transactions will not. |
| 58 | SINGLE_RESULT = 1 << 0, |
| 59 | // Query the cache or the network. May both be used. One must be present. |
| 60 | QUERY_CACHE = 1 << 1, |
| 61 | QUERY_NETWORK = 1 << 2, |
| 62 | // TODO(noamsml): Add flag for flushing cache when feature is implemented |
| 63 | // Mask of all possible flags on MDnsTransaction. |
| 64 | FLAG_MASK = (1 << 3) - 1, |
| 65 | }; |
| 66 | |
| 67 | typedef base::Callback<void(Result, const RecordParsed*)> |
| 68 | ResultCallback; |
| 69 | |
| 70 | // Destroying the transaction cancels it. |
| 71 | virtual ~MDnsTransaction() {} |
| 72 | |
| 73 | // Start the transaction. Return true on success. Cache-based transactions |
| 74 | // will execute the callback synchronously. |
| 75 | virtual bool Start() = 0; |
| 76 | |
| 77 | // Get the host or service name for the transaction. |
| 78 | virtual const std::string& GetName() const = 0; |
| 79 | |
| 80 | // Get the type for this transaction (SRV, TXT, A, AAA, etc) |
Avi Drissman | 13fc893 | 2015-12-20 04:40:46 | [diff] [blame] | 81 | virtual uint16_t GetType() const = 0; |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 82 | }; |
| 83 | |
| 84 | // A listener listens for updates regarding a specific record or set of records. |
| 85 | // Created by the MDnsClient (see |MDnsClient::CreateListener|) and used to keep |
| 86 | // track of listeners. |
[email protected] | 2ef49b3 | 2013-06-20 20:17:09 | [diff] [blame] | 87 | class NET_EXPORT MDnsListener { |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 88 | public: |
| 89 | // Used in the MDnsListener delegate to signify what type of change has been |
| 90 | // made to a record. |
| 91 | enum UpdateType { |
| 92 | RECORD_ADDED, |
| 93 | RECORD_CHANGED, |
| 94 | RECORD_REMOVED |
| 95 | }; |
| 96 | |
| 97 | class Delegate { |
| 98 | public: |
| 99 | virtual ~Delegate() {} |
| 100 | |
| 101 | // Called when a record is added, removed or updated. |
| 102 | virtual void OnRecordUpdate(UpdateType update, |
| 103 | const RecordParsed* record) = 0; |
| 104 | |
| 105 | // Called when a record is marked nonexistent by an NSEC record. |
| 106 | virtual void OnNsecRecord(const std::string& name, unsigned type) = 0; |
| 107 | |
| 108 | // Called when the cache is purged (due, for example, ot the network |
| 109 | // disconnecting). |
| 110 | virtual void OnCachePurged() = 0; |
| 111 | }; |
| 112 | |
| 113 | // Destroying the listener stops listening. |
| 114 | virtual ~MDnsListener() {} |
| 115 | |
| 116 | // Start the listener. Return true on success. |
| 117 | virtual bool Start() = 0; |
| 118 | |
[email protected] | bdd6c3d | 2014-01-30 08:07:42 | [diff] [blame] | 119 | // Actively refresh any received records. |
| 120 | virtual void SetActiveRefresh(bool active_refresh) = 0; |
| 121 | |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 122 | // Get the host or service name for this query. |
| 123 | // Return an empty string for no name. |
| 124 | virtual const std::string& GetName() const = 0; |
| 125 | |
| 126 | // Get the type for this query (SRV, TXT, A, AAA, etc) |
Avi Drissman | 13fc893 | 2015-12-20 04:40:46 | [diff] [blame] | 127 | virtual uint16_t GetType() const = 0; |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 128 | }; |
| 129 | |
[email protected] | 95b331b4 | 2013-12-02 06:26:31 | [diff] [blame] | 130 | // Creates bound datagram sockets ready to use by MDnsClient. |
| 131 | class NET_EXPORT MDnsSocketFactory { |
| 132 | public: |
| 133 | virtual ~MDnsSocketFactory() {} |
olli.raula | d8734f2c7 | 2015-12-03 12:36:34 | [diff] [blame] | 134 | virtual void CreateSockets( |
danakj | 22f90e7 | 2016-04-16 01:55:40 | [diff] [blame] | 135 | std::vector<std::unique_ptr<DatagramServerSocket>>* sockets) = 0; |
[email protected] | 95b331b4 | 2013-12-02 06:26:31 | [diff] [blame] | 136 | |
danakj | 22f90e7 | 2016-04-16 01:55:40 | [diff] [blame] | 137 | static std::unique_ptr<MDnsSocketFactory> CreateDefault(); |
[email protected] | 95b331b4 | 2013-12-02 06:26:31 | [diff] [blame] | 138 | }; |
| 139 | |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 140 | // Listens for Multicast DNS on the local network. You can access information |
| 141 | // regarding multicast DNS either by creating an |MDnsListener| to be notified |
| 142 | // of new records, or by creating an |MDnsTransaction| to look up the value of a |
| 143 | // specific records. When all listeners and active transactions are destroyed, |
| 144 | // the client stops listening on the network and destroys the cache. |
[email protected] | 2ef49b3 | 2013-06-20 20:17:09 | [diff] [blame] | 145 | class NET_EXPORT MDnsClient { |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 146 | public: |
| 147 | virtual ~MDnsClient() {} |
| 148 | |
[email protected] | 21df1696 | 2013-07-01 17:39:53 | [diff] [blame] | 149 | // Create listener object for RRType |rrtype| and name |name|. |
danakj | 22f90e7 | 2016-04-16 01:55:40 | [diff] [blame] | 150 | virtual std::unique_ptr<MDnsListener> CreateListener( |
Avi Drissman | 13fc893 | 2015-12-20 04:40:46 | [diff] [blame] | 151 | uint16_t rrtype, |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 152 | const std::string& name, |
| 153 | MDnsListener::Delegate* delegate) = 0; |
| 154 | |
| 155 | // Create a transaction that can be used to query either the MDns cache, the |
| 156 | // network, or both for records of type |rrtype| and name |name|. |flags| is |
| 157 | // defined by MDnsTransactionFlags. |
danakj | 22f90e7 | 2016-04-16 01:55:40 | [diff] [blame] | 158 | virtual std::unique_ptr<MDnsTransaction> CreateTransaction( |
Avi Drissman | 13fc893 | 2015-12-20 04:40:46 | [diff] [blame] | 159 | uint16_t rrtype, |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 160 | const std::string& name, |
| 161 | int flags, |
| 162 | const MDnsTransaction::ResultCallback& callback) = 0; |
| 163 | |
[email protected] | 95b331b4 | 2013-12-02 06:26:31 | [diff] [blame] | 164 | virtual bool StartListening(MDnsSocketFactory* factory) = 0; |
[email protected] | 9c61d25 | 2013-07-02 23:26:22 | [diff] [blame] | 165 | |
| 166 | // Do not call this inside callbacks from related MDnsListener and |
| 167 | // MDnsTransaction objects. |
| 168 | virtual void StopListening() = 0; |
| 169 | virtual bool IsListening() const = 0; |
| 170 | |
[email protected] | 0b11ec7 | 2013-07-03 08:17:42 | [diff] [blame] | 171 | // Create the default MDnsClient |
danakj | 22f90e7 | 2016-04-16 01:55:40 | [diff] [blame] | 172 | static std::unique_ptr<MDnsClient> CreateDefault(); |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 173 | }; |
| 174 | |
[email protected] | 90d3214 | 2013-12-10 10:53:06 | [diff] [blame] | 175 | NET_EXPORT IPEndPoint GetMDnsIPEndPoint(AddressFamily address_family); |
| 176 | |
Avi Drissman | 13fc893 | 2015-12-20 04:40:46 | [diff] [blame] | 177 | typedef std::vector<std::pair<uint32_t, AddressFamily>> |
| 178 | InterfaceIndexFamilyList; |
[email protected] | 90d3214 | 2013-12-10 10:53:06 | [diff] [blame] | 179 | // Returns pairs of interface and address family to bind. Current |
| 180 | // implementation returns unique list of all available interfaces. |
| 181 | NET_EXPORT InterfaceIndexFamilyList GetMDnsInterfacesToBind(); |
| 182 | |
| 183 | // Create sockets, binds socket to MDns endpoint, and sets multicast interface |
| 184 | // and joins multicast group on for |interface_index|. |
| 185 | // Returns NULL if failed. |
danakj | 22f90e7 | 2016-04-16 01:55:40 | [diff] [blame] | 186 | NET_EXPORT std::unique_ptr<DatagramServerSocket> CreateAndBindMDnsSocket( |
[email protected] | 90d3214 | 2013-12-10 10:53:06 | [diff] [blame] | 187 | AddressFamily address_family, |
Avi Drissman | 13fc893 | 2015-12-20 04:40:46 | [diff] [blame] | 188 | uint32_t interface_index); |
[email protected] | 7604fa22 | 2013-09-19 06:07:04 | [diff] [blame] | 189 | |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 190 | } // namespace net |
[email protected] | 90d3214 | 2013-12-10 10:53:06 | [diff] [blame] | 191 | |
[email protected] | 245b164e | 2013-06-13 22:31:42 | [diff] [blame] | 192 | #endif // NET_DNS_MDNS_CLIENT_H_ |