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

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 false;
gene 2013/07/18 08:55:28 return false?
Vitaly Buka (NO REVIEWS) 2013/07/18 18:16:16 yes. here we have mdns_client_!=NULL and service_d
Vitaly Buka (NO REVIEWS) 2013/07/18 18:18:38 I see :-)
Vitaly Buka (NO REVIEWS) 2013/07/18 18:20:42 Done.
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(service_watchers_.find(id) == service_watchers_.end()); 170 DCHECK(service_watchers_.find(id) == service_watchers_.end());
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) {
58 ServiceWatchers::iterator it = service_watchers_.find(id); 182 ServiceWatchers::iterator it = service_watchers_.find(id);
59 DCHECK(it != service_watchers_.end()); 183 DCHECK(it != service_watchers_.end());
60 if (it != service_watchers_.end()) 184 if (it != service_watchers_.end())
61 it->second->DiscoverNewServices(force_update); 185 it->second->DiscoverNewServices(force_update);
62 } 186 }
63 187
64 void ServiceDiscoveryMessageHandler::OnDestroyWatcher(uint64 id) { 188 void ServiceDiscoveryMessageHandler::OnDestroyWatcher(uint64 id) {
65 DCHECK(service_watchers_.find(id) != service_watchers_.end()); 189 DCHECK(service_watchers_.find(id) != service_watchers_.end());
66 service_watchers_.erase(id); 190 service_watchers_.erase(id);
67 } 191 }
68 192
69 void ServiceDiscoveryMessageHandler::OnResolveService( 193 void ServiceDiscoveryMessageHandler::OnResolveService(
70 uint64 id, 194 uint64 id,
71 const std::string& service_name) { 195 const std::string& service_name) {
72 Initialize(); 196 if (!Initialize())
197 return;
73 DCHECK(service_resolvers_.find(id) == service_resolvers_.end()); 198 DCHECK(service_resolvers_.find(id) == service_resolvers_.end());
74 scoped_ptr<ServiceResolver> resolver( 199 scoped_ptr<ServiceResolver> resolver(
75 service_discovery_client_->CreateServiceResolver( 200 service_discovery_client_->CreateServiceResolver(
76 service_name, 201 service_name,
77 base::Bind(&ServiceDiscoveryMessageHandler::OnServiceResolved, 202 base::Bind(&ServiceDiscoveryMessageHandler::OnServiceResolved,
78 base::Unretained(this), id))); 203 base::Unretained(this), id)));
79 resolver->StartResolving(); 204 resolver->StartResolving();
80 service_resolvers_[id].reset(resolver.release()); 205 service_resolvers_[id].reset(resolver.release());
81 } 206 }
82 207
(...skipping 12 matching lines...) Expand all
95 220
96 void ServiceDiscoveryMessageHandler::OnServiceResolved( 221 void ServiceDiscoveryMessageHandler::OnServiceResolved(
97 uint64 id, 222 uint64 id,
98 ServiceResolver::RequestStatus status, 223 ServiceResolver::RequestStatus status,
99 const ServiceDescription& description) { 224 const ServiceDescription& description) {
100 content::UtilityThread::Get()->Send( 225 content::UtilityThread::Get()->Send(
101 new LocalDiscoveryHostMsg_ResolverCallback(id, status, description)); 226 new LocalDiscoveryHostMsg_ResolverCallback(id, status, description));
102 } 227 }
103 228
104 } // namespace local_discovery 229 } // namespace local_discovery
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698