OLD | NEW |
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 "content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.
h" | 5 #include "content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.
h" |
6 | 6 |
7 #include <cstring> | 7 #include <cstring> |
8 | 8 |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" | 11 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" |
12 #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" | 12 #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" |
13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 14 #include "content/public/browser/content_browser_client.h" |
14 #include "content/public/common/process_type.h" | 15 #include "content/public/common/process_type.h" |
15 #include "content/public/common/socket_permission_request.h" | 16 #include "content/public/common/socket_permission_request.h" |
16 #include "ipc/ipc_message_macros.h" | 17 #include "ipc/ipc_message_macros.h" |
17 #include "net/base/io_buffer.h" | 18 #include "net/base/io_buffer.h" |
18 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
19 #include "net/base/rand_callback.h" | 20 #include "net/base/rand_callback.h" |
20 #include "net/udp/udp_socket.h" | 21 #include "net/udp/udp_socket.h" |
21 #include "ppapi/c/pp_errors.h" | 22 #include "ppapi/c/pp_errors.h" |
22 #include "ppapi/c/private/ppb_net_address_private.h" | 23 #include "ppapi/c/private/ppb_net_address_private.h" |
23 #include "ppapi/host/dispatch_host_message.h" | 24 #include "ppapi/host/dispatch_host_message.h" |
(...skipping 29 matching lines...) Expand all Loading... |
53 PepperUDPSocketMessageFilter::PendingSend::~PendingSend() { | 54 PepperUDPSocketMessageFilter::PendingSend::~PendingSend() { |
54 } | 55 } |
55 | 56 |
56 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter( | 57 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter( |
57 BrowserPpapiHostImpl* host, | 58 BrowserPpapiHostImpl* host, |
58 PP_Instance instance, | 59 PP_Instance instance, |
59 bool private_api) | 60 bool private_api) |
60 : socket_options_(0), | 61 : socket_options_(0), |
61 rcvbuf_size_(0), | 62 rcvbuf_size_(0), |
62 sndbuf_size_(0), | 63 sndbuf_size_(0), |
| 64 multicast_ttl_(0), |
| 65 can_use_multicast_(PP_ERROR_FAILED), |
63 closed_(false), | 66 closed_(false), |
64 remaining_recv_slots_(UDPSocketResourceBase::kPluginReceiveBufferSlots), | 67 remaining_recv_slots_(UDPSocketResourceBase::kPluginReceiveBufferSlots), |
65 external_plugin_(host->external_plugin()), | 68 external_plugin_(host->external_plugin()), |
66 private_api_(private_api), | 69 private_api_(private_api), |
67 render_process_id_(0), | 70 render_process_id_(0), |
68 render_frame_id_(0) { | 71 render_frame_id_(0) { |
69 ++g_num_instances; | 72 ++g_num_instances; |
70 DCHECK(host); | 73 DCHECK(host); |
71 | 74 |
72 if (!host->GetRenderFrameIDsForInstance( | 75 if (!host->GetRenderFrameIDsForInstance( |
(...skipping 15 matching lines...) Expand all Loading... |
88 scoped_refptr<base::TaskRunner> | 91 scoped_refptr<base::TaskRunner> |
89 PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage( | 92 PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage( |
90 const IPC::Message& message) { | 93 const IPC::Message& message) { |
91 switch (message.type()) { | 94 switch (message.type()) { |
92 case PpapiHostMsg_UDPSocket_SetOption::ID: | 95 case PpapiHostMsg_UDPSocket_SetOption::ID: |
93 case PpapiHostMsg_UDPSocket_Close::ID: | 96 case PpapiHostMsg_UDPSocket_Close::ID: |
94 case PpapiHostMsg_UDPSocket_RecvSlotAvailable::ID: | 97 case PpapiHostMsg_UDPSocket_RecvSlotAvailable::ID: |
95 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); | 98 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); |
96 case PpapiHostMsg_UDPSocket_Bind::ID: | 99 case PpapiHostMsg_UDPSocket_Bind::ID: |
97 case PpapiHostMsg_UDPSocket_SendTo::ID: | 100 case PpapiHostMsg_UDPSocket_SendTo::ID: |
| 101 case PpapiHostMsg_UDPSocket_JoinGroup::ID: |
| 102 case PpapiHostMsg_UDPSocket_LeaveGroup::ID: |
98 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); | 103 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); |
99 } | 104 } |
100 return NULL; | 105 return NULL; |
101 } | 106 } |
102 | 107 |
103 int32_t PepperUDPSocketMessageFilter::OnResourceMessageReceived( | 108 int32_t PepperUDPSocketMessageFilter::OnResourceMessageReceived( |
104 const IPC::Message& msg, | 109 const IPC::Message& msg, |
105 ppapi::host::HostMessageContext* context) { | 110 ppapi::host::HostMessageContext* context) { |
106 PPAPI_BEGIN_MESSAGE_MAP(PepperUDPSocketMessageFilter, msg) | 111 PPAPI_BEGIN_MESSAGE_MAP(PepperUDPSocketMessageFilter, msg) |
107 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SetOption, | 112 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SetOption, |
108 OnMsgSetOption) | 113 OnMsgSetOption) |
109 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_Bind, OnMsgBind) | 114 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_Bind, OnMsgBind) |
110 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SendTo, | 115 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SendTo, |
111 OnMsgSendTo) | 116 OnMsgSendTo) |
112 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_UDPSocket_Close, | 117 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_UDPSocket_Close, |
113 OnMsgClose) | 118 OnMsgClose) |
114 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( | 119 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( |
115 PpapiHostMsg_UDPSocket_RecvSlotAvailable, OnMsgRecvSlotAvailable) | 120 PpapiHostMsg_UDPSocket_RecvSlotAvailable, OnMsgRecvSlotAvailable) |
| 121 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_JoinGroup, |
| 122 OnMsgJoinGroup) |
| 123 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_LeaveGroup, |
| 124 OnMsgLeaveGroup) |
116 PPAPI_END_MESSAGE_MAP() | 125 PPAPI_END_MESSAGE_MAP() |
117 return PP_ERROR_FAILED; | 126 return PP_ERROR_FAILED; |
118 } | 127 } |
119 | 128 |
120 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( | 129 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( |
121 const ppapi::host::HostMessageContext* context, | 130 const ppapi::host::HostMessageContext* context, |
122 PP_UDPSocket_Option name, | 131 PP_UDPSocket_Option name, |
123 const ppapi::SocketOptionData& value) { | 132 const ppapi::SocketOptionData& value) { |
124 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 133 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
125 | 134 |
(...skipping 18 matching lines...) Expand all Loading... |
144 } else { | 153 } else { |
145 socket_options_ &= ~SOCKET_OPTION_ADDRESS_REUSE; | 154 socket_options_ &= ~SOCKET_OPTION_ADDRESS_REUSE; |
146 } | 155 } |
147 return PP_OK; | 156 return PP_OK; |
148 } | 157 } |
149 case PP_UDPSOCKET_OPTION_BROADCAST: { | 158 case PP_UDPSOCKET_OPTION_BROADCAST: { |
150 bool boolean_value = false; | 159 bool boolean_value = false; |
151 if (!value.GetBool(&boolean_value)) | 160 if (!value.GetBool(&boolean_value)) |
152 return PP_ERROR_BADARGUMENT; | 161 return PP_ERROR_BADARGUMENT; |
153 | 162 |
154 // If the socket is already connected, proxy the value to TCPSocket. | 163 // If the socket is already bound, proxy the value to UDPSocket. |
155 if (socket_.get()) | 164 if (socket_.get()) |
156 return NetErrorToPepperError(socket_->SetBroadcast(boolean_value)); | 165 return NetErrorToPepperError(socket_->SetBroadcast(boolean_value)); |
157 | 166 |
158 // UDPSocket instance is not yet created, so remember the value here. | 167 // UDPSocket instance is not yet created, so remember the value here. |
159 if (boolean_value) { | 168 if (boolean_value) { |
160 socket_options_ |= SOCKET_OPTION_BROADCAST; | 169 socket_options_ |= SOCKET_OPTION_BROADCAST; |
161 } else { | 170 } else { |
162 socket_options_ &= ~SOCKET_OPTION_BROADCAST; | 171 socket_options_ &= ~SOCKET_OPTION_BROADCAST; |
163 } | 172 } |
164 return PP_OK; | 173 return PP_OK; |
165 } | 174 } |
166 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: { | 175 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: { |
167 int32_t integer_value = 0; | 176 int32_t integer_value = 0; |
168 if (!value.GetInt32(&integer_value) || | 177 if (!value.GetInt32(&integer_value) || |
169 integer_value <= 0 || | 178 integer_value <= 0 || |
170 integer_value > | 179 integer_value > |
171 ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize) | 180 ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize) |
172 return PP_ERROR_BADARGUMENT; | 181 return PP_ERROR_BADARGUMENT; |
173 | 182 |
174 // If the socket is already connected, proxy the value to UDPSocket. | 183 // If the socket is already bound, proxy the value to UDPSocket. |
175 if (socket_.get()) { | 184 if (socket_.get()) { |
176 return NetErrorToPepperError( | 185 return NetErrorToPepperError( |
177 socket_->SetSendBufferSize(integer_value)); | 186 socket_->SetSendBufferSize(integer_value)); |
178 } | 187 } |
179 | 188 |
180 // UDPSocket instance is not yet created, so remember the value here. | 189 // UDPSocket instance is not yet created, so remember the value here. |
181 socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE; | 190 socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE; |
182 sndbuf_size_ = integer_value; | 191 sndbuf_size_ = integer_value; |
183 return PP_OK; | 192 return PP_OK; |
184 } | 193 } |
185 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: { | 194 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: { |
186 int32_t integer_value = 0; | 195 int32_t integer_value = 0; |
187 if (!value.GetInt32(&integer_value) || | 196 if (!value.GetInt32(&integer_value) || |
188 integer_value <= 0 || | 197 integer_value <= 0 || |
189 integer_value > | 198 integer_value > |
190 ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize) | 199 ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize) |
191 return PP_ERROR_BADARGUMENT; | 200 return PP_ERROR_BADARGUMENT; |
192 | 201 |
193 // If the socket is already connected, proxy the value to UDPSocket. | 202 // If the socket is already bound, proxy the value to UDPSocket. |
194 if (socket_.get()) { | 203 if (socket_.get()) { |
195 return NetErrorToPepperError( | 204 return NetErrorToPepperError( |
196 socket_->SetReceiveBufferSize(integer_value)); | 205 socket_->SetReceiveBufferSize(integer_value)); |
197 } | 206 } |
198 | 207 |
199 // UDPSocket instance is not yet created, so remember the value here. | 208 // UDPSocket instance is not yet created, so remember the value here. |
200 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE; | 209 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE; |
201 rcvbuf_size_ = integer_value; | 210 rcvbuf_size_ = integer_value; |
202 return PP_OK; | 211 return PP_OK; |
203 } | 212 } |
| 213 case PP_UDPSOCKET_OPTION_MULTICAST_LOOP: { |
| 214 bool boolean_value = false; |
| 215 if (!value.GetBool(&boolean_value)) |
| 216 return PP_ERROR_BADARGUMENT; |
| 217 |
| 218 // If the socket is already bound, proxy the value to UDPSocket. |
| 219 if (socket_) { |
| 220 if (can_use_multicast_ != PP_OK) |
| 221 return can_use_multicast_; |
| 222 |
| 223 return NetErrorToPepperError( |
| 224 socket_->SetMulticastLoopbackMode(boolean_value)); |
| 225 } |
| 226 |
| 227 // UDPSocket instance is not yet created, so remember the value here. |
| 228 if (boolean_value) { |
| 229 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP; |
| 230 } else { |
| 231 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP; |
| 232 } |
| 233 return PP_OK; |
| 234 } |
| 235 case PP_UDPSOCKET_OPTION_MULTICAST_TTL: { |
| 236 int32_t integer_value = 0; |
| 237 if (!value.GetInt32(&integer_value) || |
| 238 integer_value < 0 || integer_value > 255) |
| 239 return PP_ERROR_BADARGUMENT; |
| 240 |
| 241 // If the socket is already bound, proxy the value to UDPSocket. |
| 242 if (socket_) { |
| 243 if (can_use_multicast_ != PP_OK) |
| 244 return can_use_multicast_; |
| 245 |
| 246 return NetErrorToPepperError( |
| 247 socket_->SetMulticastTimeToLive(integer_value)); |
| 248 } |
| 249 |
| 250 // UDPSocket instance is not yet created, so remember the value here. |
| 251 socket_options_ |= SOCKET_OPTION_MULTICAST_TTL; |
| 252 multicast_ttl_ = integer_value; |
| 253 return PP_OK; |
| 254 } |
204 default: { | 255 default: { |
205 NOTREACHED(); | 256 NOTREACHED(); |
206 return PP_ERROR_BADARGUMENT; | 257 return PP_ERROR_BADARGUMENT; |
207 } | 258 } |
208 } | 259 } |
209 } | 260 } |
210 | 261 |
211 int32_t PepperUDPSocketMessageFilter::OnMsgBind( | 262 int32_t PepperUDPSocketMessageFilter::OnMsgBind( |
212 const ppapi::host::HostMessageContext* context, | 263 const ppapi::host::HostMessageContext* context, |
213 const PP_NetAddress_Private& addr) { | 264 const PP_NetAddress_Private& addr) { |
214 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 265 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
215 DCHECK(context); | 266 DCHECK(context); |
216 | 267 |
| 268 // Check for permissions to use multicast APIS. This check must be done while |
| 269 // on the UI thread, so we cache the value here to be used later on. |
| 270 PP_NetAddress_Private any_addr; |
| 271 NetAddressPrivateImpl::GetAnyAddress(PP_FALSE, &any_addr); |
| 272 can_use_multicast_ = CanUseMulticastAPI(any_addr); |
| 273 |
217 SocketPermissionRequest request = | 274 SocketPermissionRequest request = |
218 pepper_socket_utils::CreateSocketPermissionRequest( | 275 pepper_socket_utils::CreateSocketPermissionRequest( |
219 SocketPermissionRequest::UDP_BIND, addr); | 276 SocketPermissionRequest::UDP_BIND, addr); |
220 if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, | 277 if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, |
221 private_api_, | 278 private_api_, |
222 &request, | 279 &request, |
223 render_process_id_, | 280 render_process_id_, |
224 render_frame_id_)) { | 281 render_frame_id_)) { |
225 return PP_ERROR_NOACCESS; | 282 return PP_ERROR_NOACCESS; |
226 } | 283 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 } | 336 } |
280 | 337 |
281 if (!recvfrom_buffer_.get() && !closed_ && socket_.get()) { | 338 if (!recvfrom_buffer_.get() && !closed_ && socket_.get()) { |
282 DCHECK_EQ(1u, remaining_recv_slots_); | 339 DCHECK_EQ(1u, remaining_recv_slots_); |
283 DoRecvFrom(); | 340 DoRecvFrom(); |
284 } | 341 } |
285 | 342 |
286 return PP_OK; | 343 return PP_OK; |
287 } | 344 } |
288 | 345 |
| 346 int32_t PepperUDPSocketMessageFilter::OnMsgJoinGroup( |
| 347 const ppapi::host::HostMessageContext* context, |
| 348 const PP_NetAddress_Private& addr) { |
| 349 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 350 |
| 351 int32_t ret = CanUseMulticastAPI(addr); |
| 352 if (ret != PP_OK) |
| 353 return ret; |
| 354 |
| 355 if (!socket_) |
| 356 return PP_ERROR_FAILED; |
| 357 |
| 358 net::IPAddressNumber group; |
| 359 uint16 port; |
| 360 |
| 361 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port)) |
| 362 return PP_ERROR_ADDRESS_INVALID; |
| 363 |
| 364 return NetErrorToPepperError(socket_->JoinGroup(group)); |
| 365 } |
| 366 |
| 367 int32_t PepperUDPSocketMessageFilter::OnMsgLeaveGroup( |
| 368 const ppapi::host::HostMessageContext* context, |
| 369 const PP_NetAddress_Private& addr) { |
| 370 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 371 |
| 372 int32_t ret = CanUseMulticastAPI(addr); |
| 373 if (ret != PP_OK) |
| 374 return ret; |
| 375 |
| 376 if (!socket_) |
| 377 return PP_ERROR_FAILED; |
| 378 |
| 379 net::IPAddressNumber group; |
| 380 uint16 port; |
| 381 |
| 382 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port)) |
| 383 return PP_ERROR_ADDRESS_INVALID; |
| 384 |
| 385 return NetErrorToPepperError(socket_->LeaveGroup(group)); |
| 386 } |
| 387 |
289 void PepperUDPSocketMessageFilter::DoBind( | 388 void PepperUDPSocketMessageFilter::DoBind( |
290 const ppapi::host::ReplyMessageContext& context, | 389 const ppapi::host::ReplyMessageContext& context, |
291 const PP_NetAddress_Private& addr) { | 390 const PP_NetAddress_Private& addr) { |
292 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 391 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
293 | 392 |
294 if (closed_ || socket_.get()) { | 393 if (closed_ || socket_.get()) { |
295 SendBindError(context, PP_ERROR_FAILED); | 394 SendBindError(context, PP_ERROR_FAILED); |
296 return; | 395 return; |
297 } | 396 } |
298 | 397 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 return; | 435 return; |
337 } | 436 } |
338 } | 437 } |
339 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) { | 438 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) { |
340 int net_result = socket->SetReceiveBufferSize(rcvbuf_size_); | 439 int net_result = socket->SetReceiveBufferSize(rcvbuf_size_); |
341 if (net_result != net::OK) { | 440 if (net_result != net::OK) { |
342 SendBindError(context, NetErrorToPepperError(net_result)); | 441 SendBindError(context, NetErrorToPepperError(net_result)); |
343 return; | 442 return; |
344 } | 443 } |
345 } | 444 } |
| 445 if (socket_options_ & SOCKET_OPTION_MULTICAST_LOOP) { |
| 446 if (can_use_multicast_ != PP_OK) { |
| 447 SendBindError(context, NetErrorToPepperError(can_use_multicast_)); |
| 448 return; |
| 449 } |
| 450 |
| 451 int net_result = socket->SetMulticastLoopbackMode(true); |
| 452 if (net_result != net::OK) { |
| 453 SendBindError(context, NetErrorToPepperError(net_result)); |
| 454 return; |
| 455 } |
| 456 } |
| 457 if (socket_options_ & SOCKET_OPTION_MULTICAST_TTL) { |
| 458 if (can_use_multicast_ != PP_OK) { |
| 459 SendBindError(context, NetErrorToPepperError(can_use_multicast_)); |
| 460 return; |
| 461 } |
| 462 |
| 463 int net_result = socket->SetMulticastTimeToLive(multicast_ttl_); |
| 464 if (net_result != net::OK) { |
| 465 SendBindError(context, NetErrorToPepperError(net_result)); |
| 466 return; |
| 467 } |
| 468 } |
346 | 469 |
347 { | 470 { |
348 int net_result = socket->Bind(end_point); | 471 int net_result = socket->Bind(end_point); |
349 if (net_result != net::OK) { | 472 if (net_result != net::OK) { |
350 SendBindError(context, NetErrorToPepperError(net_result)); | 473 SendBindError(context, NetErrorToPepperError(net_result)); |
351 return; | 474 return; |
352 } | 475 } |
353 } | 476 } |
354 | 477 |
355 net::IPEndPoint bound_address; | 478 net::IPEndPoint bound_address; |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 SendRecvFromResult(result, std::string(), | 686 SendRecvFromResult(result, std::string(), |
564 NetAddressPrivateImpl::kInvalidNetAddress); | 687 NetAddressPrivateImpl::kInvalidNetAddress); |
565 } | 688 } |
566 | 689 |
567 void PepperUDPSocketMessageFilter::SendSendToError( | 690 void PepperUDPSocketMessageFilter::SendSendToError( |
568 const ppapi::host::ReplyMessageContext& context, | 691 const ppapi::host::ReplyMessageContext& context, |
569 int32_t result) { | 692 int32_t result) { |
570 SendSendToReply(context, result, 0); | 693 SendSendToReply(context, result, 0); |
571 } | 694 } |
572 | 695 |
| 696 int32_t PepperUDPSocketMessageFilter::CanUseMulticastAPI( |
| 697 const PP_NetAddress_Private& addr) { |
| 698 // Check for Dev API. |
| 699 // TODO(etrunko): remove check when Multicast API reaches beta/stable. |
| 700 // https://crbug.com/464452 |
| 701 ContentBrowserClient* content_browser_client = GetContentClient()->browser(); |
| 702 if (!content_browser_client->IsPluginAllowedToUseDevChannelAPIs(nullptr, |
| 703 GURL())) { |
| 704 return PP_ERROR_NOTSUPPORTED; |
| 705 } |
| 706 |
| 707 // Check for plugin permissions. |
| 708 SocketPermissionRequest request = |
| 709 pepper_socket_utils::CreateSocketPermissionRequest( |
| 710 SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, addr); |
| 711 if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, |
| 712 private_api_, |
| 713 &request, |
| 714 render_process_id_, |
| 715 render_frame_id_)) { |
| 716 return PP_ERROR_NOACCESS; |
| 717 } |
| 718 |
| 719 return PP_OK; |
| 720 } |
| 721 |
573 } // namespace content | 722 } // namespace content |
OLD | NEW |