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" |
(...skipping 11 matching lines...) Expand all Loading... | |
22 #include "ppapi/c/private/ppb_net_address_private.h" | 22 #include "ppapi/c/private/ppb_net_address_private.h" |
23 #include "ppapi/host/dispatch_host_message.h" | 23 #include "ppapi/host/dispatch_host_message.h" |
24 #include "ppapi/host/error_conversion.h" | 24 #include "ppapi/host/error_conversion.h" |
25 #include "ppapi/host/host_message_context.h" | 25 #include "ppapi/host/host_message_context.h" |
26 #include "ppapi/host/ppapi_host.h" | 26 #include "ppapi/host/ppapi_host.h" |
27 #include "ppapi/host/resource_host.h" | 27 #include "ppapi/host/resource_host.h" |
28 #include "ppapi/proxy/ppapi_messages.h" | 28 #include "ppapi/proxy/ppapi_messages.h" |
29 #include "ppapi/proxy/udp_socket_resource_base.h" | 29 #include "ppapi/proxy/udp_socket_resource_base.h" |
30 #include "ppapi/shared_impl/private/net_address_private_impl.h" | 30 #include "ppapi/shared_impl/private/net_address_private_impl.h" |
31 #include "ppapi/shared_impl/socket_option_data.h" | 31 #include "ppapi/shared_impl/socket_option_data.h" |
32 #include "ppapi/thunk/enter.h" | |
33 #include "ppapi/thunk/ppb_net_address_api.h" | |
32 | 34 |
33 using ppapi::NetAddressPrivateImpl; | 35 using ppapi::NetAddressPrivateImpl; |
34 using ppapi::host::NetErrorToPepperError; | 36 using ppapi::host::NetErrorToPepperError; |
35 using ppapi::proxy::UDPSocketResourceBase; | 37 using ppapi::proxy::UDPSocketResourceBase; |
38 using ppapi::thunk::EnterResource; | |
39 using ppapi::thunk::PPB_NetAddress_API; | |
36 | 40 |
37 namespace { | 41 namespace { |
38 | 42 |
39 size_t g_num_instances = 0; | 43 size_t g_num_instances = 0; |
40 | 44 |
41 } // namespace | 45 } // namespace |
42 | 46 |
43 namespace content { | 47 namespace content { |
44 | 48 |
45 PepperUDPSocketMessageFilter::PendingSend::PendingSend( | 49 PepperUDPSocketMessageFilter::PendingSend::PendingSend( |
46 const net::IPAddressNumber& address, | 50 const net::IPAddressNumber& address, |
47 int port, | 51 int port, |
48 const scoped_refptr<net::IOBufferWithSize>& buffer, | 52 const scoped_refptr<net::IOBufferWithSize>& buffer, |
49 const ppapi::host::ReplyMessageContext& context) | 53 const ppapi::host::ReplyMessageContext& context) |
50 : address(address), port(port), buffer(buffer), context(context) { | 54 : address(address), port(port), buffer(buffer), context(context) { |
51 } | 55 } |
52 | 56 |
53 PepperUDPSocketMessageFilter::PendingSend::~PendingSend() { | 57 PepperUDPSocketMessageFilter::PendingSend::~PendingSend() { |
54 } | 58 } |
55 | 59 |
56 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter( | 60 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter( |
57 BrowserPpapiHostImpl* host, | 61 BrowserPpapiHostImpl* host, |
58 PP_Instance instance, | 62 PP_Instance instance, |
59 bool private_api) | 63 bool private_api) |
60 : socket_options_(0), | 64 : socket_options_(0), |
61 rcvbuf_size_(0), | 65 rcvbuf_size_(0), |
62 sndbuf_size_(0), | 66 sndbuf_size_(0), |
67 multicast_ttl_(0), | |
63 closed_(false), | 68 closed_(false), |
64 remaining_recv_slots_(UDPSocketResourceBase::kPluginReceiveBufferSlots), | 69 remaining_recv_slots_(UDPSocketResourceBase::kPluginReceiveBufferSlots), |
65 external_plugin_(host->external_plugin()), | 70 external_plugin_(host->external_plugin()), |
66 private_api_(private_api), | 71 private_api_(private_api), |
67 render_process_id_(0), | 72 render_process_id_(0), |
68 render_frame_id_(0) { | 73 render_frame_id_(0) { |
69 ++g_num_instances; | 74 ++g_num_instances; |
70 DCHECK(host); | 75 DCHECK(host); |
71 | 76 |
72 if (!host->GetRenderFrameIDsForInstance( | 77 if (!host->GetRenderFrameIDsForInstance( |
(...skipping 15 matching lines...) Expand all Loading... | |
88 scoped_refptr<base::TaskRunner> | 93 scoped_refptr<base::TaskRunner> |
89 PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage( | 94 PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage( |
90 const IPC::Message& message) { | 95 const IPC::Message& message) { |
91 switch (message.type()) { | 96 switch (message.type()) { |
92 case PpapiHostMsg_UDPSocket_SetOption::ID: | 97 case PpapiHostMsg_UDPSocket_SetOption::ID: |
93 case PpapiHostMsg_UDPSocket_Close::ID: | 98 case PpapiHostMsg_UDPSocket_Close::ID: |
94 case PpapiHostMsg_UDPSocket_RecvSlotAvailable::ID: | 99 case PpapiHostMsg_UDPSocket_RecvSlotAvailable::ID: |
95 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); | 100 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); |
96 case PpapiHostMsg_UDPSocket_Bind::ID: | 101 case PpapiHostMsg_UDPSocket_Bind::ID: |
97 case PpapiHostMsg_UDPSocket_SendTo::ID: | 102 case PpapiHostMsg_UDPSocket_SendTo::ID: |
103 case PpapiHostMsg_UDPSocket_JoinGroup::ID: | |
104 case PpapiHostMsg_UDPSocket_LeaveGroup::ID: | |
98 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); | 105 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); |
99 } | 106 } |
100 return NULL; | 107 return NULL; |
101 } | 108 } |
102 | 109 |
103 int32_t PepperUDPSocketMessageFilter::OnResourceMessageReceived( | 110 int32_t PepperUDPSocketMessageFilter::OnResourceMessageReceived( |
104 const IPC::Message& msg, | 111 const IPC::Message& msg, |
105 ppapi::host::HostMessageContext* context) { | 112 ppapi::host::HostMessageContext* context) { |
106 PPAPI_BEGIN_MESSAGE_MAP(PepperUDPSocketMessageFilter, msg) | 113 PPAPI_BEGIN_MESSAGE_MAP(PepperUDPSocketMessageFilter, msg) |
107 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SetOption, | 114 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SetOption, |
108 OnMsgSetOption) | 115 OnMsgSetOption) |
109 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_Bind, OnMsgBind) | 116 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_Bind, OnMsgBind) |
110 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SendTo, | 117 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SendTo, |
111 OnMsgSendTo) | 118 OnMsgSendTo) |
112 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_UDPSocket_Close, | 119 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_UDPSocket_Close, |
113 OnMsgClose) | 120 OnMsgClose) |
114 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( | 121 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( |
115 PpapiHostMsg_UDPSocket_RecvSlotAvailable, OnMsgRecvSlotAvailable) | 122 PpapiHostMsg_UDPSocket_RecvSlotAvailable, OnMsgRecvSlotAvailable) |
123 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_JoinGroup, | |
124 OnMsgJoinGroup) | |
125 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_LeaveGroup, | |
126 OnMsgLeaveGroup) | |
116 PPAPI_END_MESSAGE_MAP() | 127 PPAPI_END_MESSAGE_MAP() |
117 return PP_ERROR_FAILED; | 128 return PP_ERROR_FAILED; |
118 } | 129 } |
119 | 130 |
120 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( | 131 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( |
121 const ppapi::host::HostMessageContext* context, | 132 const ppapi::host::HostMessageContext* context, |
122 PP_UDPSocket_Option name, | 133 PP_UDPSocket_Option name, |
123 const ppapi::SocketOptionData& value) { | 134 const ppapi::SocketOptionData& value) { |
124 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 135 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
125 | 136 |
(...skipping 18 matching lines...) Expand all Loading... | |
144 } else { | 155 } else { |
145 socket_options_ &= ~SOCKET_OPTION_ADDRESS_REUSE; | 156 socket_options_ &= ~SOCKET_OPTION_ADDRESS_REUSE; |
146 } | 157 } |
147 return PP_OK; | 158 return PP_OK; |
148 } | 159 } |
149 case PP_UDPSOCKET_OPTION_BROADCAST: { | 160 case PP_UDPSOCKET_OPTION_BROADCAST: { |
150 bool boolean_value = false; | 161 bool boolean_value = false; |
151 if (!value.GetBool(&boolean_value)) | 162 if (!value.GetBool(&boolean_value)) |
152 return PP_ERROR_BADARGUMENT; | 163 return PP_ERROR_BADARGUMENT; |
153 | 164 |
154 // If the socket is already connected, proxy the value to TCPSocket. | 165 // If the socket is already connected, proxy the value to UDPSocket. |
155 if (socket_.get()) | 166 if (socket_.get()) |
156 return NetErrorToPepperError(socket_->SetBroadcast(boolean_value)); | 167 return NetErrorToPepperError(socket_->SetBroadcast(boolean_value)); |
157 | 168 |
158 // UDPSocket instance is not yet created, so remember the value here. | 169 // UDPSocket instance is not yet created, so remember the value here. |
159 if (boolean_value) { | 170 if (boolean_value) { |
160 socket_options_ |= SOCKET_OPTION_BROADCAST; | 171 socket_options_ |= SOCKET_OPTION_BROADCAST; |
161 } else { | 172 } else { |
162 socket_options_ &= ~SOCKET_OPTION_BROADCAST; | 173 socket_options_ &= ~SOCKET_OPTION_BROADCAST; |
163 } | 174 } |
164 return PP_OK; | 175 return PP_OK; |
(...skipping 29 matching lines...) Expand all Loading... | |
194 if (socket_.get()) { | 205 if (socket_.get()) { |
195 return NetErrorToPepperError( | 206 return NetErrorToPepperError( |
196 socket_->SetReceiveBufferSize(integer_value)); | 207 socket_->SetReceiveBufferSize(integer_value)); |
197 } | 208 } |
198 | 209 |
199 // UDPSocket instance is not yet created, so remember the value here. | 210 // UDPSocket instance is not yet created, so remember the value here. |
200 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE; | 211 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE; |
201 rcvbuf_size_ = integer_value; | 212 rcvbuf_size_ = integer_value; |
202 return PP_OK; | 213 return PP_OK; |
203 } | 214 } |
215 case PP_UDPSOCKET_OPTION_MULTICAST_LOOP: { | |
216 bool boolean_value = false; | |
217 if (!value.GetBool(&boolean_value)) | |
218 return PP_ERROR_BADARGUMENT; | |
219 | |
220 // If the socket is already connected, proxy the value to UDPSocket. | |
221 if (socket_.get()) | |
222 return NetErrorToPepperError( | |
223 socket_->SetMulticastLoopbackMode(boolean_value)); | |
224 | |
225 // UDPSocket instance is not yet created, so remember the value here. | |
226 if (boolean_value) { | |
227 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP; | |
228 } else { | |
229 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP; | |
230 } | |
231 return PP_OK; | |
232 } | |
233 case PP_UDPSOCKET_OPTION_MULTICAST_TTL: { | |
234 int32_t integer_value = 0; | |
235 if (!value.GetInt32(&integer_value) || | |
236 integer_value < 0 || integer_value > 255) | |
237 return PP_ERROR_BADARGUMENT; | |
238 | |
239 // If the socket is already connected, proxy the value to UDPSocket. | |
240 if (socket_.get()) | |
241 return NetErrorToPepperError( | |
242 socket_->SetMulticastTimeToLive(integer_value)); | |
243 | |
244 // UDPSocket instance is not yet created, so remember the value here. | |
245 socket_options_ |= SOCKET_OPTION_MULTICAST_TTL; | |
246 multicast_ttl_ = integer_value; | |
247 return PP_OK; | |
248 } | |
204 default: { | 249 default: { |
205 NOTREACHED(); | 250 NOTREACHED(); |
206 return PP_ERROR_BADARGUMENT; | 251 return PP_ERROR_BADARGUMENT; |
207 } | 252 } |
208 } | 253 } |
209 } | 254 } |
210 | 255 |
211 int32_t PepperUDPSocketMessageFilter::OnMsgBind( | 256 int32_t PepperUDPSocketMessageFilter::OnMsgBind( |
212 const ppapi::host::HostMessageContext* context, | 257 const ppapi::host::HostMessageContext* context, |
213 const PP_NetAddress_Private& addr) { | 258 const PP_NetAddress_Private& addr) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
279 } | 324 } |
280 | 325 |
281 if (!recvfrom_buffer_.get() && !closed_ && socket_.get()) { | 326 if (!recvfrom_buffer_.get() && !closed_ && socket_.get()) { |
282 DCHECK_EQ(1u, remaining_recv_slots_); | 327 DCHECK_EQ(1u, remaining_recv_slots_); |
283 DoRecvFrom(); | 328 DoRecvFrom(); |
284 } | 329 } |
285 | 330 |
286 return PP_OK; | 331 return PP_OK; |
287 } | 332 } |
288 | 333 |
334 int32_t PepperUDPSocketMessageFilter::OnMsgJoinGroup( | |
335 const ppapi::host::HostMessageContext* context, | |
336 const PP_NetAddress_Private& addr) { | |
337 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
338 DCHECK(context); | |
339 | |
340 if (!socket_.get()) | |
341 return PP_ERROR_FAILED; | |
342 | |
343 net::IPAddressNumber group; | |
344 uint16 port; | |
345 | |
346 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port)) | |
347 return PP_ERROR_ADDRESS_INVALID; | |
348 | |
bbudge
2015/02/19 21:27:04
We should add a TODO comment here to check for mul
etrunko
2015/02/23 22:09:10
Done.
| |
349 return NetErrorToPepperError(socket_->JoinGroup(group)); | |
350 } | |
351 | |
352 int32_t PepperUDPSocketMessageFilter::OnMsgLeaveGroup( | |
353 const ppapi::host::HostMessageContext* context, | |
354 const PP_NetAddress_Private& addr) { | |
355 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
356 DCHECK(context); | |
357 | |
358 if (!socket_.get()) | |
359 return PP_ERROR_FAILED; | |
360 | |
361 net::IPAddressNumber group; | |
362 uint16 port; | |
363 | |
364 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port)) | |
365 return PP_ERROR_ADDRESS_INVALID; | |
366 | |
367 return NetErrorToPepperError(socket_->LeaveGroup(group)); | |
368 } | |
369 | |
289 void PepperUDPSocketMessageFilter::DoBind( | 370 void PepperUDPSocketMessageFilter::DoBind( |
290 const ppapi::host::ReplyMessageContext& context, | 371 const ppapi::host::ReplyMessageContext& context, |
291 const PP_NetAddress_Private& addr) { | 372 const PP_NetAddress_Private& addr) { |
292 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 373 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
293 | 374 |
294 if (closed_ || socket_.get()) { | 375 if (closed_ || socket_.get()) { |
295 SendBindError(context, PP_ERROR_FAILED); | 376 SendBindError(context, PP_ERROR_FAILED); |
296 return; | 377 return; |
297 } | 378 } |
298 | 379 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
336 return; | 417 return; |
337 } | 418 } |
338 } | 419 } |
339 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) { | 420 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) { |
340 int net_result = socket->SetReceiveBufferSize(rcvbuf_size_); | 421 int net_result = socket->SetReceiveBufferSize(rcvbuf_size_); |
341 if (net_result != net::OK) { | 422 if (net_result != net::OK) { |
342 SendBindError(context, NetErrorToPepperError(net_result)); | 423 SendBindError(context, NetErrorToPepperError(net_result)); |
343 return; | 424 return; |
344 } | 425 } |
345 } | 426 } |
427 if (socket_options_ & SOCKET_OPTION_MULTICAST_LOOP) { | |
428 int net_result = socket->SetMulticastLoopbackMode(true); | |
429 if (net_result != net::OK) { | |
430 SendBindError(context, NetErrorToPepperError(net_result)); | |
431 return; | |
432 } | |
433 } | |
434 if (socket_options_ & SOCKET_OPTION_MULTICAST_TTL) { | |
435 int net_result = socket->SetMulticastInterface(multicast_ttl_); | |
436 if (net_result != net::OK) { | |
437 SendBindError(context, NetErrorToPepperError(net_result)); | |
438 return; | |
439 } | |
440 } | |
346 | 441 |
347 { | 442 { |
348 int net_result = socket->Bind(end_point); | 443 int net_result = socket->Bind(end_point); |
349 if (net_result != net::OK) { | 444 if (net_result != net::OK) { |
350 SendBindError(context, NetErrorToPepperError(net_result)); | 445 SendBindError(context, NetErrorToPepperError(net_result)); |
351 return; | 446 return; |
352 } | 447 } |
353 } | 448 } |
354 | 449 |
355 net::IPEndPoint bound_address; | 450 net::IPEndPoint bound_address; |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
564 NetAddressPrivateImpl::kInvalidNetAddress); | 659 NetAddressPrivateImpl::kInvalidNetAddress); |
565 } | 660 } |
566 | 661 |
567 void PepperUDPSocketMessageFilter::SendSendToError( | 662 void PepperUDPSocketMessageFilter::SendSendToError( |
568 const ppapi::host::ReplyMessageContext& context, | 663 const ppapi::host::ReplyMessageContext& context, |
569 int32_t result) { | 664 int32_t result) { |
570 SendSendToReply(context, result, 0); | 665 SendSendToReply(context, result, 0); |
571 } | 666 } |
572 | 667 |
573 } // namespace content | 668 } // namespace content |
OLD | NEW |