17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file. 47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#ifndef NET_DNS_MDNS_CLIENT_H_ 67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define NET_DNS_MDNS_CLIENT_H_ 77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <string> 97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <vector> 107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/callback.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/base/ip_endpoint.h" 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/dns/dns_query.h" 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/dns/dns_response.h" 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/dns/record_parsed.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace net { 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class DatagramServerSocket; 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class RecordParsed; 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Represents a one-time record lookup. A transaction takes one 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// associated callback (see |MDnsClient::CreateTransaction|) and calls it 247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// whenever a matching record has been found, either from the cache or 257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// by querying the network (it may choose to query either or both based on its 267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// creation flags, see MDnsTransactionFlags). Network-based transactions will 277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// time out after a reasonable number of seconds. 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass NET_EXPORT MDnsTransaction { 297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public: 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Used to signify what type of result the transaction has received. 317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) enum Result { 327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Passed whenever a record is found. 337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RESULT_RECORD, 347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // The transaction is done. Applies to non-single-valued transactions. Is 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // called when the transaction has finished (this is the last call to the 367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // callback). 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RESULT_DONE, 387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // No results have been found. Applies to single-valued transactions. Is 397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // called when the transaction has finished without finding any results. 407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // For transactions that use the network, this happens when a timeout 417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // occurs, for transactions that are cache-only, this happens when no 427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // results are in the cache. 437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RESULT_NO_RESULTS, 447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Called when an NSec record is read for this transaction's 457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // query. This means there cannot possibly be a record of the type 467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // and name for this transaction. 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RESULT_NSEC 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) }; 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Used when creating an MDnsTransaction. 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) enum Flags { 527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Transaction should return only one result, and stop listening after it. 537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Note that single result transactions will signal when their timeout is 547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // reached, whereas multi-result transactions will not. 557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SINGLE_RESULT = 1 << 0, 567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Query the cache or the network. May both be used. One must be present. 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) QUERY_CACHE = 1 << 1, 587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) QUERY_NETWORK = 1 << 2, 597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // TODO(noamsml): Add flag for flushing cache when feature is implemented 607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Mask of all possible flags on MDnsTransaction. 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) FLAG_MASK = (1 << 3) - 1, 627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) }; 637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) typedef base::Callback<void(Result, const RecordParsed*)> 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResultCallback; 667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Destroying the transaction cancels it. 687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual ~MDnsTransaction() {} 697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Start the transaction. Return true on success. Cache-based transactions 717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // will execute the callback synchronously. 727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual bool Start() = 0; 737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Get the host or service name for the transaction. 757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual const std::string& GetName() const = 0; 767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Get the type for this transaction (SRV, TXT, A, AAA, etc) 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual uint16 GetType() const = 0; 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}; 807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// A listener listens for updates regarding a specific record or set of records. 827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Created by the MDnsClient (see |MDnsClient::CreateListener|) and used to keep 837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// track of listeners. 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass NET_EXPORT MDnsListener { 857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public: 867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Used in the MDnsListener delegate to signify what type of change has been 877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // made to a record. 887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) enum UpdateType { 897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RECORD_ADDED, 907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RECORD_CHANGED, 917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RECORD_REMOVED 927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) }; 937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) class Delegate { 957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public: 967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual ~Delegate() {} 977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Called when a record is added, removed or updated. 997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual void OnRecordUpdate(UpdateType update, 1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const RecordParsed* record) = 0; 1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Called when a record is marked nonexistent by an NSEC record. 1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual void OnNsecRecord(const std::string& name, unsigned type) = 0; 1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Called when the cache is purged (due, for example, ot the network 1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // disconnecting). 1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual void OnCachePurged() = 0; 1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) }; 1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Destroying the listener stops listening. 1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual ~MDnsListener() {} 1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Start the listener. Return true on success. 1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual bool Start() = 0; 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Actively refresh any received records. 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void SetActiveRefresh(bool active_refresh) = 0; 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Get the host or service name for this query. 1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Return an empty string for no name. 1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual const std::string& GetName() const = 0; 1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Get the type for this query (SRV, TXT, A, AAA, etc) 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual uint16 GetType() const = 0; 1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}; 1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Creates bound datagram sockets ready to use by MDnsClient. 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class NET_EXPORT MDnsSocketFactory { 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~MDnsSocketFactory() {} 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void CreateSockets(ScopedVector<DatagramServerSocket>* sockets) = 0; 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static scoped_ptr<MDnsSocketFactory> CreateDefault(); 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Listens for Multicast DNS on the local network. You can access information 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// regarding multicast DNS either by creating an |MDnsListener| to be notified 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// of new records, or by creating an |MDnsTransaction| to look up the value of a 1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// specific records. When all listeners and active transactions are destroyed, 1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// the client stops listening on the network and destroys the cache. 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass NET_EXPORT MDnsClient { 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public: 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual ~MDnsClient() {} 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create listener object for RRType |rrtype| and name |name|. 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual scoped_ptr<MDnsListener> CreateListener( 1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) uint16 rrtype, 1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& name, 1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) MDnsListener::Delegate* delegate) = 0; 1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Create a transaction that can be used to query either the MDns cache, the 1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // network, or both for records of type |rrtype| and name |name|. |flags| is 1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // defined by MDnsTransactionFlags. 1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual scoped_ptr<MDnsTransaction> CreateTransaction( 1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) uint16 rrtype, 1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& name, 1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int flags, 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const MDnsTransaction::ResultCallback& callback) = 0; 1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual bool StartListening(MDnsSocketFactory* factory) = 0; 1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Do not call this inside callbacks from related MDnsListener and 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // MDnsTransaction objects. 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void StopListening() = 0; 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual bool IsListening() const = 0; 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create the default MDnsClient 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static scoped_ptr<MDnsClient> CreateDefault(); 1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}; 1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)NET_EXPORT IPEndPoint GetMDnsIPEndPoint(AddressFamily address_family); 172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)typedef std::vector<std::pair<uint32, AddressFamily> > InterfaceIndexFamilyList; 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Returns pairs of interface and address family to bind. Current 175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// implementation returns unique list of all available interfaces. 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)NET_EXPORT InterfaceIndexFamilyList GetMDnsInterfacesToBind(); 177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Create sockets, binds socket to MDns endpoint, and sets multicast interface 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// and joins multicast group on for |interface_index|. 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Returns NULL if failed. 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)NET_EXPORT scoped_ptr<DatagramServerSocket> CreateAndBindMDnsSocket( 182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddressFamily address_family, 183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 interface_index); 184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace net 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif // NET_DNS_MDNS_CLIENT_H_ 188