1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// found in the LICENSE file. 4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/utility/local_discovery/service_discovery_message_handler.h" 6ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 7bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include <algorithm> 8bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/lazy_instance.h" 10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/common/local_discovery/local_discovery_messages.h" 115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/common/local_discovery/service_discovery_client_impl.h" 12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/public/utility/utility_thread.h" 13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/socket/socket_descriptor.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/udp/datagram_server_socket.h" 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace local_discovery { 17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace { 19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ClosePlatformSocket(net::SocketDescriptor socket); 21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Sets socket factory used by |net::CreatePlatformSocket|. Implemetation 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// keeps single socket that will be returned to the first call to 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// |net::CreatePlatformSocket| during object lifetime. 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class ScopedSocketFactory : public net::PlatformSocketFactory { 26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public: 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) explicit ScopedSocketFactory(net::SocketDescriptor socket) : socket_(socket) { 28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::PlatformSocketFactory::SetInstance(this); 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~ScopedSocketFactory() { 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::PlatformSocketFactory::SetInstance(NULL); 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ClosePlatformSocket(socket_); 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) socket_ = net::kInvalidSocket; 35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual net::SocketDescriptor CreateSocket(int family, int type, 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int protocol) OVERRIDE { 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_EQ(type, SOCK_DGRAM); 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(family == AF_INET || family == AF_INET6); 4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) net::SocketDescriptor result = net::kInvalidSocket; 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::swap(result, socket_); 43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return result; 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 45ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 46bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch private: 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::SocketDescriptor socket_; 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ScopedSocketFactory); 49ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}; 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)struct SocketInfo { 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SocketInfo(net::SocketDescriptor socket, 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::AddressFamily address_family, 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 interface_index) 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : socket(socket), 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) address_family(address_family), 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) interface_index(interface_index) { 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::SocketDescriptor socket; 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::AddressFamily address_family; 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) uint32 interface_index; 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Returns list of sockets preallocated before. 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class PreCreatedMDnsSocketFactory : public net::MDnsSocketFactory { 66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public: 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PreCreatedMDnsSocketFactory() {} 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual ~PreCreatedMDnsSocketFactory() { 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Not empty if process exits too fast, before starting mDns code. If 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // happened, destructors may crash accessing destroyed global objects. 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sockets_.weak_clear(); 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // net::MDnsSocketFactory implementation: 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void CreateSockets( 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ScopedVector<net::DatagramServerSocket>* sockets) OVERRIDE { 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sockets->swap(sockets_); 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Reset(); 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void AddSocket(const SocketInfo& socket_info) { 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Takes ownership of socket_info.socket; 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedSocketFactory platform_factory(socket_info.socket); 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<net::DatagramServerSocket> socket( 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::CreateAndBindMDnsSocket(socket_info.address_family, 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) socket_info.interface_index)); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (socket) { 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) socket->DetachFromThread(); 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sockets_.push_back(socket.release()); 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void Reset() { 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sockets_.clear(); 95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch private: 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedVector<net::DatagramServerSocket> sockets_; 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PreCreatedMDnsSocketFactory); 101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}; 102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::LazyInstance<PreCreatedMDnsSocketFactory> 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) g_local_discovery_socket_factory = LAZY_INSTANCE_INITIALIZER; 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_WIN) 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ClosePlatformSocket(net::SocketDescriptor socket) { 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ::closesocket(socket); 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void StaticInitializeSocketFactory() { 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::InterfaceIndexFamilyList interfaces(net::GetMDnsInterfacesToBind()); 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (size_t i = 0; i < interfaces.size(); ++i) { 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(interfaces[i].second == net::ADDRESS_FAMILY_IPV4 || 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) interfaces[i].second == net::ADDRESS_FAMILY_IPV6); 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::SocketDescriptor descriptor = 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::CreatePlatformSocket( 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) net::ConvertAddressFamily(interfaces[i].second), SOCK_DGRAM, 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IPPROTO_UDP); 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) g_local_discovery_socket_factory.Get().AddSocket( 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SocketInfo(descriptor, interfaces[i].second, interfaces[i].first)); 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 126ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#else // OS_WIN 127ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ClosePlatformSocket(net::SocketDescriptor socket) { 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ::close(socket); 13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void StaticInitializeSocketFactory() { 13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif // OS_WIN 136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void SendHostMessageOnUtilityThread(IPC::Message* msg) { 13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::UtilityThread::Get()->Send(msg); 139ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::string WatcherUpdateToString(ServiceWatcher::UpdateType update) { 14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) switch (update) { 14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ServiceWatcher::UPDATE_ADDED: 14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "UPDATE_ADDED"; 14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ServiceWatcher::UPDATE_CHANGED: 14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "UPDATE_CHANGED"; 14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ServiceWatcher::UPDATE_REMOVED: 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "UPDATE_REMOVED"; 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ServiceWatcher::UPDATE_INVALIDATED: 15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "UPDATE_INVALIDATED"; 15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "Unknown Update"; 15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::string ResolverStatusToString(ServiceResolver::RequestStatus status) { 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) switch (status) { 15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ServiceResolver::STATUS_SUCCESS: 15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "STATUS_SUCESS"; 15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ServiceResolver::STATUS_REQUEST_TIMEOUT: 16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "STATUS_REQUEST_TIMEOUT"; 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ServiceResolver::STATUS_KNOWN_NONEXISTENT: 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "STATUS_KNOWN_NONEXISTENT"; 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "Unknown Status"; 16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 167ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} // namespace 168ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 169ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochServiceDiscoveryMessageHandler::ServiceDiscoveryMessageHandler() { 170ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 171ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 172ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochServiceDiscoveryMessageHandler::~ServiceDiscoveryMessageHandler() { 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!discovery_thread_); 174ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 175ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 176ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::PreSandboxStartup() { 17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) StaticInitializeSocketFactory(); 178ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 179ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 180ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::InitializeMdns() { 181ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (service_discovery_client_ || mdns_client_) 182ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 183ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 184ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch mdns_client_ = net::MDnsClient::CreateDefault(); 185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool result = 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mdns_client_->StartListening(g_local_discovery_socket_factory.Pointer()); 187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Close unused sockets. 188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) g_local_discovery_socket_factory.Get().Reset(); 189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!result) { 190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) VLOG(1) << "Failed to start MDnsClient"; 191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Send(new LocalDiscoveryHostMsg_Error()); 192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 193ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 194ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 195ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_discovery_client_.reset( 196ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new local_discovery::ServiceDiscoveryClientImpl(mdns_client_.get())); 197ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 198ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 199ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ServiceDiscoveryMessageHandler::InitializeThread() { 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (discovery_task_runner_.get()) 201ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 202ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (discovery_thread_) 203ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 204ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch utility_task_runner_ = base::MessageLoop::current()->message_loop_proxy(); 205ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch discovery_thread_.reset(new base::Thread("ServiceDiscoveryThread")); 206ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); 207ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (discovery_thread_->StartWithOptions(thread_options)) { 208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch discovery_task_runner_ = discovery_thread_->message_loop_proxy(); 209ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch discovery_task_runner_->PostTask(FROM_HERE, 210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::InitializeMdns, 211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this))); 212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return discovery_task_runner_.get() != NULL; 214ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 216ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ServiceDiscoveryMessageHandler::OnMessageReceived( 217ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const IPC::Message& message) { 218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool handled = true; 219ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_BEGIN_MESSAGE_MAP(ServiceDiscoveryMessageHandler, message) 22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_POSIX) 22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_SetSockets, OnSetSockets) 22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif // OS_POSIX 223ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_StartWatcher, OnStartWatcher) 224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DiscoverServices, OnDiscoverServices) 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_SetActivelyRefreshServices, 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnSetActivelyRefreshServices) 227ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DestroyWatcher, OnDestroyWatcher) 228ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_ResolveService, OnResolveService) 229ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DestroyResolver, OnDestroyResolver) 230bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_ResolveLocalDomain, 231bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch OnResolveLocalDomain) 232bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DestroyLocalDomainResolver, 233bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch OnDestroyLocalDomainResolver) 2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_ShutdownLocalDiscovery, 2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ShutdownLocalDiscovery) 236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_UNHANDLED(handled = false) 237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_END_MESSAGE_MAP() 238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return handled; 239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 240ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::PostTask( 242ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const tracked_objects::Location& from_here, 243ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::Closure& task) { 244ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!InitializeThread()) 245ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 246ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch discovery_task_runner_->PostTask(from_here, task); 247ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_POSIX) 25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ServiceDiscoveryMessageHandler::OnSetSockets( 251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::vector<LocalDiscoveryMsg_SocketInfo>& sockets) { 252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (size_t i = 0; i < sockets.size(); ++i) { 253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) g_local_discovery_socket_factory.Get().AddSocket( 254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SocketInfo(sockets[i].descriptor.fd, sockets[i].address_family, 255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sockets[i].interface_index)); 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif // OS_POSIX 25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 260ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnStartWatcher( 261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& service_type) { 263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PostTask(FROM_HERE, 264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::StartWatcher, 265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id, service_type)); 266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnDiscoverServices(uint64 id, 269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool force_update) { 270ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PostTask(FROM_HERE, 271ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::DiscoverServices, 272ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id, force_update)); 273ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceDiscoveryMessageHandler::OnSetActivelyRefreshServices( 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint64 id, bool actively_refresh_services) { 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PostTask(FROM_HERE, 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind( 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &ServiceDiscoveryMessageHandler::SetActivelyRefreshServices, 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this), id, actively_refresh_services)); 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 283ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnDestroyWatcher(uint64 id) { 284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PostTask(FROM_HERE, 285ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::DestroyWatcher, 286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id)); 287ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnResolveService( 290ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& service_name) { 292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PostTask(FROM_HERE, 293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::ResolveService, 294ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id, service_name)); 295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 296ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 297ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnDestroyResolver(uint64 id) { 298ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PostTask(FROM_HERE, 299ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::DestroyResolver, 300ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id)); 301ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 302ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 303bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ServiceDiscoveryMessageHandler::OnResolveLocalDomain( 304bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch uint64 id, const std::string& domain, 305bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch net::AddressFamily address_family) { 306bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch PostTask(FROM_HERE, 307bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::ResolveLocalDomain, 308bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Unretained(this), id, domain, address_family)); 309bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 310bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 311bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ServiceDiscoveryMessageHandler::OnDestroyLocalDomainResolver(uint64 id) { 312bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch PostTask(FROM_HERE, 313bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind( 314bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch &ServiceDiscoveryMessageHandler::DestroyLocalDomainResolver, 315bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Unretained(this), id)); 316bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 317bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 318ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::StartWatcher( 319ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 320ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& service_type) { 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) VLOG(1) << "StartWatcher, id=" << id << ", type=" << service_type; 322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!service_discovery_client_) 323ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(!ContainsKey(service_watchers_, id)); 325ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<ServiceWatcher> watcher( 326ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_discovery_client_->CreateServiceWatcher( 327ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_type, 328ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::OnServiceUpdated, 329ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id))); 330ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch watcher->Start(); 331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_watchers_[id].reset(watcher.release()); 332ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 333ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 334ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::DiscoverServices(uint64 id, 335ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool force_update) { 3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) VLOG(1) << "DiscoverServices, id=" << id; 337ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!service_discovery_client_) 338ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 339ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(ContainsKey(service_watchers_, id)); 340ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_watchers_[id]->DiscoverNewServices(force_update); 341ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 342ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceDiscoveryMessageHandler::SetActivelyRefreshServices( 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint64 id, 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool actively_refresh_services) { 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "ActivelyRefreshServices, id=" << id; 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!service_discovery_client_) 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(ContainsKey(service_watchers_, id)); 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) service_watchers_[id]->SetActivelyRefreshServices(actively_refresh_services); 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 353ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::DestroyWatcher(uint64 id) { 3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) VLOG(1) << "DestoryWatcher, id=" << id; 355ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!service_discovery_client_) 356ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 357ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_watchers_.erase(id); 358ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 359ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 360ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::ResolveService( 361ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 362ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& service_name) { 3634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) VLOG(1) << "ResolveService, id=" << id << ", name=" << service_name; 364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!service_discovery_client_) 365ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 366ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(!ContainsKey(service_resolvers_, id)); 367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<ServiceResolver> resolver( 368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_discovery_client_->CreateServiceResolver( 369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_name, 370ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::OnServiceResolved, 371ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id))); 372ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch resolver->StartResolving(); 373ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_resolvers_[id].reset(resolver.release()); 374ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 375ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 376ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::DestroyResolver(uint64 id) { 3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) VLOG(1) << "DestroyResolver, id=" << id; 378ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!service_discovery_client_) 379ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 380ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_resolvers_.erase(id); 381ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 382ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 383bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ServiceDiscoveryMessageHandler::ResolveLocalDomain( 384bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch uint64 id, 385bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const std::string& domain, 386bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch net::AddressFamily address_family) { 3874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) VLOG(1) << "ResolveLocalDomain, id=" << id << ", domain=" << domain; 388bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!service_discovery_client_) 389bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return; 390bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(!ContainsKey(local_domain_resolvers_, id)); 391bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<LocalDomainResolver> resolver( 392bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch service_discovery_client_->CreateLocalDomainResolver( 393bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch domain, address_family, 394bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::OnLocalDomainResolved, 395bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Unretained(this), id))); 396bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch resolver->Start(); 397bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch local_domain_resolvers_[id].reset(resolver.release()); 398bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 399bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 400bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ServiceDiscoveryMessageHandler::DestroyLocalDomainResolver(uint64 id) { 4014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) VLOG(1) << "DestroyLocalDomainResolver, id=" << id; 402bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!service_discovery_client_) 403bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return; 404bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch local_domain_resolvers_.erase(id); 405bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 406bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ServiceDiscoveryMessageHandler::ShutdownLocalDiscovery() { 4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!discovery_task_runner_.get()) 4094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) discovery_task_runner_->PostTask( 4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FROM_HERE, 4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&ServiceDiscoveryMessageHandler::ShutdownOnIOThread, 4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Unretained(this))); 4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This will wait for message loop to drain, so ShutdownOnIOThread will 4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // definitely be called. 4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) discovery_thread_.reset(); 4193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ServiceDiscoveryMessageHandler::ShutdownOnIOThread() { 4224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) VLOG(1) << "ShutdownLocalDiscovery"; 4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service_watchers_.clear(); 4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service_resolvers_.clear(); 4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) local_domain_resolvers_.clear(); 4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service_discovery_client_.reset(); 4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mdns_client_.reset(); 4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 430ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnServiceUpdated( 431ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 432ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceWatcher::UpdateType update, 433ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& name) { 4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) VLOG(1) << "OnServiceUpdated, id=" << id 4354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << ", status=" << WatcherUpdateToString(update) << ", name=" << name; 436ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(service_discovery_client_); 43768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 43868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Send(new LocalDiscoveryHostMsg_WatcherCallback(id, update, name)); 439ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 440ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 441ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnServiceResolved( 442ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 443ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceResolver::RequestStatus status, 444ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const ServiceDescription& description) { 4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) VLOG(1) << "OnServiceResolved, id=" << id 4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << ", status=" << ResolverStatusToString(status) 4474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << ", name=" << description.service_name; 44858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 449ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(service_discovery_client_); 45068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Send(new LocalDiscoveryHostMsg_ResolverCallback(id, status, description)); 451ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 452ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 453bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ServiceDiscoveryMessageHandler::OnLocalDomainResolved( 454bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch uint64 id, 455bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch bool success, 456424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const net::IPAddressNumber& address_ipv4, 457424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const net::IPAddressNumber& address_ipv6) { 4584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) VLOG(1) << "OnLocalDomainResolved, id=" << id 4591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << ", IPv4=" << (address_ipv4.empty() ? "" : 4601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) net::IPAddressToString(address_ipv4)) 4611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << ", IPv6=" << (address_ipv6.empty() ? "" : 4621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) net::IPAddressToString(address_ipv6)); 46358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 464bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(service_discovery_client_); 46568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Send(new LocalDiscoveryHostMsg_LocalDomainResolverCallback( 46668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) id, success, address_ipv4, address_ipv6)); 467bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 468bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 46968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ServiceDiscoveryMessageHandler::Send(IPC::Message* msg) { 47068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) utility_task_runner_->PostTask(FROM_HERE, 47168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&SendHostMessageOnUtilityThread, 47268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) msg)); 47368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 474ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 475bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} // namespace local_discovery 476