service_discovery_message_handler.cc revision 3551c9c881056c480085172ff9840cab31610854
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 9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/command_line.h" 10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/common/local_discovery/local_discovery_messages.h" 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/utility/local_discovery/service_discovery_client_impl.h" 12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/public/common/content_switches.h" 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/public/utility/utility_thread.h" 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/lazy_instance.h" 18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "net/base/winsock_init.h" 19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "net/base/winsock_util.h" 20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif // OS_WIN 22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace local_discovery { 24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace { 26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool NeedsSockets() { 28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoSandbox) && 29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CommandLine::ForCurrentProcess()->HasSwitch( 30ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch switches::kUtilityProcessEnableMDns); 31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 33ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#if defined(OS_WIN) 34ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass SocketFactory : public net::PlatformSocketFactory { 36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public: 37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SocketFactory() 38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch : socket_v4_(NULL), 39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch socket_v6_(NULL) { 40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch net::EnsureWinsockInit(); 41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch socket_v4_ = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch WSA_FLAG_OVERLAPPED); 43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch socket_v6_ = WSASocket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch WSA_FLAG_OVERLAPPED); 45ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 46ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 47ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch void Reset() { 48ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (socket_v4_ != INVALID_SOCKET) { 49ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch closesocket(socket_v4_); 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch socket_v4_ = INVALID_SOCKET; 51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (socket_v6_ != INVALID_SOCKET) { 53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch closesocket(socket_v6_); 54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch socket_v6_ = INVALID_SOCKET; 55ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 56ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch virtual ~SocketFactory() { 59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Reset(); 60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch virtual SOCKET CreateSocket(int family, int type, int protocol) OVERRIDE { 63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SOCKET result = INVALID_SOCKET; 64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (type != SOCK_DGRAM && protocol != IPPROTO_UDP) { 65ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch NOTREACHED(); 66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else if (family == AF_INET) { 67ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::swap(result, socket_v4_); 68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else if (family == AF_INET6) { 69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::swap(result, socket_v6_); 70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return result; 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SOCKET socket_v4_; 75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SOCKET socket_v6_; 76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 77bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch private: 78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DISALLOW_COPY_AND_ASSIGN(SocketFactory); 79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}; 80ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 81ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbase::LazyInstance<SocketFactory> 82ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch g_local_discovery_socket_factory = LAZY_INSTANCE_INITIALIZER; 83ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 84ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass ScopedSocketFactorySetter { 85ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public: 86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ScopedSocketFactorySetter() { 87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (NeedsSockets()) { 88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch net::PlatformSocketFactory::SetInstance( 89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch &g_local_discovery_socket_factory.Get()); 90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ~ScopedSocketFactorySetter() { 94ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (NeedsSockets()) { 95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch net::PlatformSocketFactory::SetInstance(NULL); 96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch g_local_discovery_socket_factory.Get().Reset(); 97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 98ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch static void Initialize() { 101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (NeedsSockets()) { 102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch g_local_discovery_socket_factory.Get(); 103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 104ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 105ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 106ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch private: 107ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DISALLOW_COPY_AND_ASSIGN(ScopedSocketFactorySetter); 108ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}; 109ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 110ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#else // OS_WIN 111ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 112ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass ScopedSocketFactorySetter { 113ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public: 114ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ScopedSocketFactorySetter() {} 115ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 116ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch static void Initialize() { 117ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // TODO(vitalybuka) : implement socket access from sandbox for other 118ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // platforms. 119ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(!NeedsSockets()); 120ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 121ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}; 122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 123ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#endif // OS_WIN 124ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid SendServiceResolved(uint64 id, ServiceResolver::RequestStatus status, 126ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const ServiceDescription& description) { 127ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch content::UtilityThread::Get()->Send( 128ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new LocalDiscoveryHostMsg_ResolverCallback(id, status, description)); 129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid SendServiceUpdated(uint64 id, ServiceWatcher::UpdateType update, 132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& name) { 133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch content::UtilityThread::Get()->Send( 134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new LocalDiscoveryHostMsg_WatcherCallback(id, update, name)); 135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 137bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid SendLocalDomainResolved(uint64 id, bool success, 138bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const net::IPAddressNumber& address) { 139bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch content::UtilityThread::Get()->Send( 140bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch new LocalDiscoveryHostMsg_LocalDomainResolverCallback( 141bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch id, success, address)); 142bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 143ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} // namespace 145ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 146ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochServiceDiscoveryMessageHandler::ServiceDiscoveryMessageHandler() { 147ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 148ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 149ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochServiceDiscoveryMessageHandler::~ServiceDiscoveryMessageHandler() { 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!discovery_thread_); 151ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 152ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 153ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::PreSandboxStartup() { 154ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ScopedSocketFactorySetter::Initialize(); 155ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 156ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 157ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::InitializeMdns() { 158ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (service_discovery_client_ || mdns_client_) 159ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 160ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 161ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch mdns_client_ = net::MDnsClient::CreateDefault(); 162ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch { 163ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Temporarily redirect network code to use pre-created sockets. 164ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ScopedSocketFactorySetter socket_factory_setter; 165ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!mdns_client_->StartListening()) 166ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 167ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 168ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 169ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_discovery_client_.reset( 170ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch new local_discovery::ServiceDiscoveryClientImpl(mdns_client_.get())); 171ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 172ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 173ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ServiceDiscoveryMessageHandler::InitializeThread() { 174ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (discovery_task_runner_) 175ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 176ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (discovery_thread_) 177ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 178ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch utility_task_runner_ = base::MessageLoop::current()->message_loop_proxy(); 179ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch discovery_thread_.reset(new base::Thread("ServiceDiscoveryThread")); 180ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); 181ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (discovery_thread_->StartWithOptions(thread_options)) { 182ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch discovery_task_runner_ = discovery_thread_->message_loop_proxy(); 183ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch discovery_task_runner_->PostTask(FROM_HERE, 184ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::InitializeMdns, 185ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this))); 186ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 187ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return discovery_task_runner_ != NULL; 188ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 189ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 190ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ServiceDiscoveryMessageHandler::OnMessageReceived( 191ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const IPC::Message& message) { 192ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool handled = true; 193ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_BEGIN_MESSAGE_MAP(ServiceDiscoveryMessageHandler, message) 194ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_StartWatcher, OnStartWatcher) 195ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DiscoverServices, OnDiscoverServices) 196ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DestroyWatcher, OnDestroyWatcher) 197ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_ResolveService, OnResolveService) 198ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DestroyResolver, OnDestroyResolver) 199bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_ResolveLocalDomain, 200bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch OnResolveLocalDomain) 201bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DestroyLocalDomainResolver, 202bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch OnDestroyLocalDomainResolver) 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_ShutdownLocalDiscovery, 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ShutdownLocalDiscovery) 205ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_MESSAGE_UNHANDLED(handled = false) 206ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch IPC_END_MESSAGE_MAP() 207ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return handled; 208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 209ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::PostTask( 211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const tracked_objects::Location& from_here, 212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::Closure& task) { 213ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!InitializeThread()) 214ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch discovery_task_runner_->PostTask(from_here, task); 216ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 217ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnStartWatcher( 219ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 220ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& service_type) { 221ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PostTask(FROM_HERE, 222ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::StartWatcher, 223ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id, service_type)); 224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 225ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnDiscoverServices(uint64 id, 227ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool force_update) { 228ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PostTask(FROM_HERE, 229ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::DiscoverServices, 230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id, force_update)); 231ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 233ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnDestroyWatcher(uint64 id) { 234ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PostTask(FROM_HERE, 235ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::DestroyWatcher, 236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id)); 237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnResolveService( 240ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& service_name) { 242ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PostTask(FROM_HERE, 243ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::ResolveService, 244ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id, service_name)); 245ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 246ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 247ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnDestroyResolver(uint64 id) { 248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PostTask(FROM_HERE, 249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::DestroyResolver, 250ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id)); 251ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 252ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 253bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ServiceDiscoveryMessageHandler::OnResolveLocalDomain( 254bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch uint64 id, const std::string& domain, 255bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch net::AddressFamily address_family) { 256bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch PostTask(FROM_HERE, 257bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::ResolveLocalDomain, 258bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Unretained(this), id, domain, address_family)); 259bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 260bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 261bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ServiceDiscoveryMessageHandler::OnDestroyLocalDomainResolver(uint64 id) { 262bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch PostTask(FROM_HERE, 263bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind( 264bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch &ServiceDiscoveryMessageHandler::DestroyLocalDomainResolver, 265bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Unretained(this), id)); 266bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 267bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::StartWatcher( 269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 270ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& service_type) { 271ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!service_discovery_client_) 272ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 273ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(!ContainsKey(service_watchers_, id)); 274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<ServiceWatcher> watcher( 275ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_discovery_client_->CreateServiceWatcher( 276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_type, 277ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::OnServiceUpdated, 278ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id))); 279ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch watcher->Start(); 280ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_watchers_[id].reset(watcher.release()); 281ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 282ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 283ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::DiscoverServices(uint64 id, 284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool force_update) { 285ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!service_discovery_client_) 286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 287ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(ContainsKey(service_watchers_, id)); 288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_watchers_[id]->DiscoverNewServices(force_update); 289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 290ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::DestroyWatcher(uint64 id) { 292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!service_discovery_client_) 293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 294ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(ContainsKey(service_watchers_, id)); 295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_watchers_.erase(id); 296ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 297ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 298ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::ResolveService( 299ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 300ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& service_name) { 301ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!service_discovery_client_) 302ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 303ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(!ContainsKey(service_resolvers_, id)); 304ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<ServiceResolver> resolver( 305ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_discovery_client_->CreateServiceResolver( 306ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_name, 307ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::OnServiceResolved, 308ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Unretained(this), id))); 309ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch resolver->StartResolving(); 310ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_resolvers_[id].reset(resolver.release()); 311ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 312ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 313ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::DestroyResolver(uint64 id) { 314ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!service_discovery_client_) 315ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 316ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(ContainsKey(service_resolvers_, id)); 317ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch service_resolvers_.erase(id); 318ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 319ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 320bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ServiceDiscoveryMessageHandler::ResolveLocalDomain( 321bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch uint64 id, 322bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const std::string& domain, 323bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch net::AddressFamily address_family) { 324bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!service_discovery_client_) 325bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return; 326bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(!ContainsKey(local_domain_resolvers_, id)); 327bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<LocalDomainResolver> resolver( 328bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch service_discovery_client_->CreateLocalDomainResolver( 329bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch domain, address_family, 330bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Bind(&ServiceDiscoveryMessageHandler::OnLocalDomainResolved, 331bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch base::Unretained(this), id))); 332bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch resolver->Start(); 333bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch local_domain_resolvers_[id].reset(resolver.release()); 334bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 335bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 336bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ServiceDiscoveryMessageHandler::DestroyLocalDomainResolver(uint64 id) { 337bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!service_discovery_client_) 338bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return; 339bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(ContainsKey(local_domain_resolvers_, id)); 340bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch local_domain_resolvers_.erase(id); 341bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 342bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ServiceDiscoveryMessageHandler::ShutdownLocalDiscovery() { 3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) discovery_task_runner_->PostTask( 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FROM_HERE, 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&ServiceDiscoveryMessageHandler::ShutdownOnIOThread, 3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Unretained(this))); 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // This will wait for message loop to drain, so ShutdownOnIOThread will 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // definitely be called. 3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) discovery_thread_.reset(); 3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ServiceDiscoveryMessageHandler::ShutdownOnIOThread() { 3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service_watchers_.clear(); 3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service_resolvers_.clear(); 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) local_domain_resolvers_.clear(); 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) service_discovery_client_.reset(); 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) mdns_client_.reset(); 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnServiceUpdated( 364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 365ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceWatcher::UpdateType update, 366ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& name) { 367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(service_discovery_client_); 368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch utility_task_runner_->PostTask(FROM_HERE, 369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&SendServiceUpdated, id, update, name)); 370ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 371ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 372ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid ServiceDiscoveryMessageHandler::OnServiceResolved( 373ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint64 id, 374ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceResolver::RequestStatus status, 375ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const ServiceDescription& description) { 376ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(service_discovery_client_); 377ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch utility_task_runner_->PostTask(FROM_HERE, 378ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&SendServiceResolved, id, status, description)); 379ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 380ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 381bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid ServiceDiscoveryMessageHandler::OnLocalDomainResolved( 382bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch uint64 id, 383bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch bool success, 384bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const net::IPAddressNumber& address) { 385bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(service_discovery_client_); 386bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch utility_task_runner_->PostTask(FROM_HERE, base::Bind(&SendLocalDomainResolved, 387bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch id, success, address)); 388bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 389bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 390ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 391bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} // namespace local_discovery 392