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