Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: chrome/utility/local_discovery/service_discovery_message_handler.cc

Issue 19737002: Enable sandbox in local discovery utility process. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/utility/local_discovery/service_discovery_message_handler.h" 5 #include "chrome/utility/local_discovery/service_discovery_message_handler.h"
6 6
7 #include "base/command_line.h"
7 #include "chrome/common/local_discovery/local_discovery_messages.h" 8 #include "chrome/common/local_discovery/local_discovery_messages.h"
8 #include "chrome/utility/local_discovery/service_discovery_client_impl.h" 9 #include "chrome/utility/local_discovery/service_discovery_client_impl.h"
10 #include "content/public/common/content_switches.h"
9 #include "content/public/utility/utility_thread.h" 11 #include "content/public/utility/utility_thread.h"
10 12
13 #if defined(OS_WIN)
14
15 #include "base/lazy_instance.h"
16 #include "net/base/winsock_init.h"
17 #include "net/base/winsock_util.h"
18
19 #endif // OS_WIN
20
21 namespace {
22
23 bool NeedsSockets() {
24 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoSandbox) &&
25 CommandLine::ForCurrentProcess()->HasSwitch(
26 switches::kUtilityProcessEnableMDns);
27 }
28
29 #if defined(OS_WIN)
30
31 class SocketFactory : public net::PlatformSocketFactory {
32 public:
33 SocketFactory()
34 : socket_v4_(NULL),
35 socket_v6_(NULL) {
36 net::EnsureWinsockInit();
37 socket_v4_ = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0,
38 WSA_FLAG_OVERLAPPED);
39 socket_v6_ = WSASocket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, NULL, 0,
40 WSA_FLAG_OVERLAPPED);
41 }
42
43 void Reset() {
44 if (socket_v4_ != INVALID_SOCKET) {
45 closesocket(socket_v4_);
46 socket_v4_ = INVALID_SOCKET;
47 }
48 if (socket_v6_ != INVALID_SOCKET) {
49 closesocket(socket_v6_);
50 socket_v6_ = INVALID_SOCKET;
51 }
52 }
53
54 virtual ~SocketFactory() {
55 Reset();
56 }
57
58 virtual SOCKET CreateSocket(int family, int type, int protocol) OVERRIDE {
59 SOCKET result = INVALID_SOCKET;
60 if (type != SOCK_DGRAM && protocol != IPPROTO_UDP) {
61 NOTREACHED();
62 } else if (family == AF_INET) {
63 std::swap(result, socket_v4_);
64 } else if (family == AF_INET6) {
65 std::swap(result, socket_v6_);
66 }
67 return result;
68 }
69
70 SOCKET socket_v4_;
71 SOCKET socket_v6_;
72
73 DISALLOW_COPY_AND_ASSIGN(SocketFactory);
74 };
75
76 base::LazyInstance<SocketFactory>
77 g_local_discovery_socket_factory = LAZY_INSTANCE_INITIALIZER;
78
79 class ScopedSocketFactorySetter {
80 public:
81 ScopedSocketFactorySetter() {
82 if (NeedsSockets()) {
83 net::PlatformSocketFactory::SetInstance(
84 &g_local_discovery_socket_factory.Get());
85 }
86 }
87
88 ~ScopedSocketFactorySetter() {
89 if (NeedsSockets()) {
90 net::PlatformSocketFactory::SetInstance(NULL);
91 g_local_discovery_socket_factory.Get().Reset();
92 }
93 }
94
95 static void Initialize() {
96 if (NeedsSockets()) {
97 g_local_discovery_socket_factory.Get();
98 }
99 }
100
101 private:
102 DISALLOW_COPY_AND_ASSIGN(ScopedSocketFactorySetter);
103 };
104
105 #elif // OS_WIN
106
107 class ScopedSocketFactorySetter {
108 static void Initialize() {
109 // TODO(vitalybuka) : implement socket access from sandbox for other
110 // platforms.
111 DCHECK(!NeedsSockets());
112 }
113 };
114
115 #endif // OS_WIN
116
117 } // namespace
118
11 namespace local_discovery { 119 namespace local_discovery {
12 120
13 ServiceDiscoveryMessageHandler::ServiceDiscoveryMessageHandler() { 121 ServiceDiscoveryMessageHandler::ServiceDiscoveryMessageHandler() {
14 } 122 }
15 123
16 ServiceDiscoveryMessageHandler::~ServiceDiscoveryMessageHandler() { 124 ServiceDiscoveryMessageHandler::~ServiceDiscoveryMessageHandler() {
17 } 125 }
18 126
19 void ServiceDiscoveryMessageHandler::Initialize() { 127 void ServiceDiscoveryMessageHandler::PreSandboxStartup() {
20 if (!service_discovery_client_) { 128 ScopedSocketFactorySetter::Initialize();
21 mdns_client_ = net::MDnsClient::CreateDefault(); 129 }
22 mdns_client_->StartListening(); 130
23 service_discovery_client_.reset( 131 bool ServiceDiscoveryMessageHandler::Initialize() {
24 new local_discovery::ServiceDiscoveryClientImpl(mdns_client_.get())); 132 if (service_discovery_client_)
133 return true;
134
135 if (mdns_client_) // We tried but failed before.
136 return false;
137
138 mdns_client_ = net::MDnsClient::CreateDefault();
139 {
140 // Temporarily redirect network code to use pre-created sockets.
141 ScopedSocketFactorySetter socket_factory_setter;
142 if (!mdns_client_->StartListening())
143 return false;
25 } 144 }
145
146 service_discovery_client_.reset(
147 new local_discovery::ServiceDiscoveryClientImpl(mdns_client_.get()));
148 return true;
26 } 149 }
27 150
28 bool ServiceDiscoveryMessageHandler::OnMessageReceived( 151 bool ServiceDiscoveryMessageHandler::OnMessageReceived(
29 const IPC::Message& message) { 152 const IPC::Message& message) {
30 bool handled = true; 153 bool handled = true;
31 IPC_BEGIN_MESSAGE_MAP(ServiceDiscoveryMessageHandler, message) 154 IPC_BEGIN_MESSAGE_MAP(ServiceDiscoveryMessageHandler, message)
32 IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_StartWatcher, OnStartWatcher) 155 IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_StartWatcher, OnStartWatcher)
33 IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DiscoverServices, OnDiscoverServices) 156 IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DiscoverServices, OnDiscoverServices)
34 IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DestroyWatcher, OnDestroyWatcher) 157 IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DestroyWatcher, OnDestroyWatcher)
35 IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_ResolveService, OnResolveService) 158 IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_ResolveService, OnResolveService)
36 IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DestroyResolver, OnDestroyResolver) 159 IPC_MESSAGE_HANDLER(LocalDiscoveryMsg_DestroyResolver, OnDestroyResolver)
37 IPC_MESSAGE_UNHANDLED(handled = false) 160 IPC_MESSAGE_UNHANDLED(handled = false)
38 IPC_END_MESSAGE_MAP() 161 IPC_END_MESSAGE_MAP()
39 return handled; 162 return handled;
40 } 163 }
41 164
42 void ServiceDiscoveryMessageHandler::OnStartWatcher( 165 void ServiceDiscoveryMessageHandler::OnStartWatcher(
43 uint64 id, 166 uint64 id,
44 const std::string& service_type) { 167 const std::string& service_type) {
45 Initialize(); 168 if (!Initialize())
169 return;
46 DCHECK(!ContainsKey(service_watchers_, id)); 170 DCHECK(!ContainsKey(service_watchers_, id));
47 scoped_ptr<ServiceWatcher> watcher( 171 scoped_ptr<ServiceWatcher> watcher(
48 service_discovery_client_->CreateServiceWatcher( 172 service_discovery_client_->CreateServiceWatcher(
49 service_type, 173 service_type,
50 base::Bind(&ServiceDiscoveryMessageHandler::OnServiceUpdated, 174 base::Bind(&ServiceDiscoveryMessageHandler::OnServiceUpdated,
51 base::Unretained(this), id))); 175 base::Unretained(this), id)));
52 watcher->Start(); 176 watcher->Start();
53 service_watchers_[id].reset(watcher.release()); 177 service_watchers_[id].reset(watcher.release());
54 } 178 }
55 179
56 void ServiceDiscoveryMessageHandler::OnDiscoverServices(uint64 id, 180 void ServiceDiscoveryMessageHandler::OnDiscoverServices(uint64 id,
57 bool force_update) { 181 bool force_update) {
182 if (!service_discovery_client_)
183 return;
58 DCHECK(ContainsKey(service_watchers_, id)); 184 DCHECK(ContainsKey(service_watchers_, id));
59 service_watchers_[id]->DiscoverNewServices(force_update); 185 service_watchers_[id]->DiscoverNewServices(force_update);
60 } 186 }
61 187
62 void ServiceDiscoveryMessageHandler::OnDestroyWatcher(uint64 id) { 188 void ServiceDiscoveryMessageHandler::OnDestroyWatcher(uint64 id) {
189 if (!service_discovery_client_)
190 return;
63 DCHECK(ContainsKey(service_watchers_, id)); 191 DCHECK(ContainsKey(service_watchers_, id));
64 service_watchers_.erase(id); 192 service_watchers_.erase(id);
65 } 193 }
66 194
67 void ServiceDiscoveryMessageHandler::OnResolveService( 195 void ServiceDiscoveryMessageHandler::OnResolveService(
68 uint64 id, 196 uint64 id,
69 const std::string& service_name) { 197 const std::string& service_name) {
70 Initialize(); 198 if (!Initialize())
199 return;
71 DCHECK(!ContainsKey(service_resolvers_, id)); 200 DCHECK(!ContainsKey(service_resolvers_, id));
72 scoped_ptr<ServiceResolver> resolver( 201 scoped_ptr<ServiceResolver> resolver(
73 service_discovery_client_->CreateServiceResolver( 202 service_discovery_client_->CreateServiceResolver(
74 service_name, 203 service_name,
75 base::Bind(&ServiceDiscoveryMessageHandler::OnServiceResolved, 204 base::Bind(&ServiceDiscoveryMessageHandler::OnServiceResolved,
76 base::Unretained(this), id))); 205 base::Unretained(this), id)));
77 resolver->StartResolving(); 206 resolver->StartResolving();
78 service_resolvers_[id].reset(resolver.release()); 207 service_resolvers_[id].reset(resolver.release());
79 } 208 }
80 209
81 void ServiceDiscoveryMessageHandler::OnDestroyResolver(uint64 id) { 210 void ServiceDiscoveryMessageHandler::OnDestroyResolver(uint64 id) {
211 if (!service_discovery_client_)
212 return;
82 DCHECK(ContainsKey(service_resolvers_, id)); 213 DCHECK(ContainsKey(service_resolvers_, id));
83 service_resolvers_.erase(id); 214 service_resolvers_.erase(id);
84 } 215 }
85 216
86 void ServiceDiscoveryMessageHandler::OnServiceUpdated( 217 void ServiceDiscoveryMessageHandler::OnServiceUpdated(
87 uint64 id, 218 uint64 id,
88 ServiceWatcher::UpdateType update, 219 ServiceWatcher::UpdateType update,
89 const std::string& name) { 220 const std::string& name) {
221 DCHECK(service_discovery_client_);
90 content::UtilityThread::Get()->Send( 222 content::UtilityThread::Get()->Send(
91 new LocalDiscoveryHostMsg_WatcherCallback(id, update, name)); 223 new LocalDiscoveryHostMsg_WatcherCallback(id, update, name));
92 } 224 }
93 225
94 void ServiceDiscoveryMessageHandler::OnServiceResolved( 226 void ServiceDiscoveryMessageHandler::OnServiceResolved(
95 uint64 id, 227 uint64 id,
96 ServiceResolver::RequestStatus status, 228 ServiceResolver::RequestStatus status,
97 const ServiceDescription& description) { 229 const ServiceDescription& description) {
230 DCHECK(service_discovery_client_);
98 content::UtilityThread::Get()->Send( 231 content::UtilityThread::Get()->Send(
99 new LocalDiscoveryHostMsg_ResolverCallback(id, status, description)); 232 new LocalDiscoveryHostMsg_ResolverCallback(id, status, description));
100 } 233 }
101 234
102 } // namespace local_discovery 235 } // namespace local_discovery
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698