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

Side by Side Diff: content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc

Issue 704133005: Pepper: Add support for multicast in PPB_UDPSocket API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase, initial unit tests Created 6 years, 1 month 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
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 "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 10 matching lines...) Expand all
21 #include "ppapi/c/private/ppb_net_address_private.h" 21 #include "ppapi/c/private/ppb_net_address_private.h"
22 #include "ppapi/host/dispatch_host_message.h" 22 #include "ppapi/host/dispatch_host_message.h"
23 #include "ppapi/host/error_conversion.h" 23 #include "ppapi/host/error_conversion.h"
24 #include "ppapi/host/host_message_context.h" 24 #include "ppapi/host/host_message_context.h"
25 #include "ppapi/host/ppapi_host.h" 25 #include "ppapi/host/ppapi_host.h"
26 #include "ppapi/host/resource_host.h" 26 #include "ppapi/host/resource_host.h"
27 #include "ppapi/proxy/ppapi_messages.h" 27 #include "ppapi/proxy/ppapi_messages.h"
28 #include "ppapi/proxy/udp_socket_resource_base.h" 28 #include "ppapi/proxy/udp_socket_resource_base.h"
29 #include "ppapi/shared_impl/private/net_address_private_impl.h" 29 #include "ppapi/shared_impl/private/net_address_private_impl.h"
30 #include "ppapi/shared_impl/socket_option_data.h" 30 #include "ppapi/shared_impl/socket_option_data.h"
31 #include "ppapi/thunk/enter.h"
32 #include "ppapi/thunk/ppb_net_address_api.h"
31 33
32 using ppapi::NetAddressPrivateImpl; 34 using ppapi::NetAddressPrivateImpl;
33 using ppapi::host::NetErrorToPepperError; 35 using ppapi::host::NetErrorToPepperError;
36 using ppapi::thunk::EnterResource;
37 using ppapi::thunk::PPB_NetAddress_API;
34 38
35 namespace { 39 namespace {
36 40
37 size_t g_num_instances = 0; 41 size_t g_num_instances = 0;
38 42
39 } // namespace 43 } // namespace
40 44
41 namespace content { 45 namespace content {
42 46
43 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter( 47 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter(
44 BrowserPpapiHostImpl* host, 48 BrowserPpapiHostImpl* host,
45 PP_Instance instance, 49 PP_Instance instance,
46 bool private_api) 50 bool private_api)
47 : allow_address_reuse_(false), 51 : allow_address_reuse_(false),
48 allow_broadcast_(false), 52 allow_broadcast_(false),
53 multicast_loop_(false),
54 multicast_interface_(0),
55 multicast_time_to_live_(0),
49 closed_(false), 56 closed_(false),
50 remaining_recv_slots_( 57 remaining_recv_slots_(
51 ppapi::proxy::UDPSocketResourceBase::kPluginReceiveBufferSlots), 58 ppapi::proxy::UDPSocketResourceBase::kPluginReceiveBufferSlots),
52 external_plugin_(host->external_plugin()), 59 external_plugin_(host->external_plugin()),
53 private_api_(private_api), 60 private_api_(private_api),
54 render_process_id_(0), 61 render_process_id_(0),
55 render_frame_id_(0) { 62 render_frame_id_(0) {
56 ++g_num_instances; 63 ++g_num_instances;
57 DCHECK(host); 64 DCHECK(host);
58 65
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 113
107 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( 114 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption(
108 const ppapi::host::HostMessageContext* context, 115 const ppapi::host::HostMessageContext* context,
109 PP_UDPSocket_Option name, 116 PP_UDPSocket_Option name,
110 const ppapi::SocketOptionData& value) { 117 const ppapi::SocketOptionData& value) {
111 DCHECK_CURRENTLY_ON(BrowserThread::IO); 118 DCHECK_CURRENTLY_ON(BrowserThread::IO);
112 119
113 if (closed_) 120 if (closed_)
114 return PP_ERROR_FAILED; 121 return PP_ERROR_FAILED;
115 122
123 // Check if socket is expected to be bound or not according to the option
116 switch (name) { 124 switch (name) {
117 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE: 125 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE:
118 case PP_UDPSOCKET_OPTION_BROADCAST: { 126 case PP_UDPSOCKET_OPTION_BROADCAST:
127 case PP_UDPSOCKET_OPTION_MULTICAST_LOOP:
128 case PP_UDPSOCKET_OPTION_MULTICAST_TTL:
129 case PP_UDPSOCKET_OPTION_MULTICAST_IF: {
119 if (socket_.get()) { 130 if (socket_.get()) {
120 // They only take effect before the socket is bound. 131 // They only take effect before the socket is bound.
121 return PP_ERROR_FAILED; 132 return PP_ERROR_FAILED;
122 } 133 }
134 break;
135 }
136 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE:
137 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE:
138 case PP_UDPSOCKET_OPTION_MULTICAST_JOIN:
139 case PP_UDPSOCKET_OPTION_MULTICAST_LEAVE: {
140 if (!socket_.get()) {
141 // They only take effect after the socket is bound.
142 return PP_ERROR_FAILED;
143 }
144 break;
145 }
146 }
123 147
148 switch (name) {
149 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE:
150 case PP_UDPSOCKET_OPTION_BROADCAST:
151 case PP_UDPSOCKET_OPTION_MULTICAST_LOOP: {
124 bool boolean_value = false; 152 bool boolean_value = false;
125 if (!value.GetBool(&boolean_value)) 153 if (!value.GetBool(&boolean_value))
126 return PP_ERROR_BADARGUMENT; 154 return PP_ERROR_BADARGUMENT;
127 155
128 if (name == PP_UDPSOCKET_OPTION_ADDRESS_REUSE) 156 if (name == PP_UDPSOCKET_OPTION_ADDRESS_REUSE)
129 allow_address_reuse_ = boolean_value; 157 allow_address_reuse_ = boolean_value;
130 else 158 else if (name == PP_UDPSOCKET_OPTION_BROADCAST)
131 allow_broadcast_ = boolean_value; 159 allow_broadcast_ = boolean_value;
160 else if (name == PP_UDPSOCKET_OPTION_MULTICAST_LOOP)
161 multicast_loop_ = boolean_value;
132 return PP_OK; 162 return PP_OK;
133 } 163 }
134 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: 164 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE:
135 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: { 165 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE:
136 if (!socket_.get()) { 166 case PP_UDPSOCKET_OPTION_MULTICAST_IF: {
137 // They only take effect after the socket is bound.
138 return PP_ERROR_FAILED;
139 }
140 int32_t integer_value = 0; 167 int32_t integer_value = 0;
141 if (!value.GetInt32(&integer_value) || integer_value <= 0) 168 if (!value.GetInt32(&integer_value) || integer_value <= 0)
142 return PP_ERROR_BADARGUMENT; 169 return PP_ERROR_BADARGUMENT;
143 170
171 if (name == PP_UDPSOCKET_OPTION_MULTICAST_IF) {
172 multicast_interface_ = integer_value;
173 return PP_OK;
174 }
175
144 int net_result = net::ERR_UNEXPECTED; 176 int net_result = net::ERR_UNEXPECTED;
145 if (name == PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE) { 177 if (name == PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE) {
146 if (integer_value > 178 if (integer_value >
147 ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize) { 179 ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize) {
148 return PP_ERROR_BADARGUMENT; 180 return PP_ERROR_BADARGUMENT;
149 } 181 }
150 net_result = socket_->SetSendBufferSize(integer_value); 182 net_result = socket_->SetSendBufferSize(integer_value);
151 } else { 183 } else {
152 if (integer_value > 184 if (integer_value >
153 ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize) { 185 ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize) {
154 return PP_ERROR_BADARGUMENT; 186 return PP_ERROR_BADARGUMENT;
155 } 187 }
156 net_result = socket_->SetReceiveBufferSize(integer_value); 188 net_result = socket_->SetReceiveBufferSize(integer_value);
157 } 189 }
158 // TODO(wtc): Add error mapping code. 190 // TODO(wtc): Add error mapping code.
159 return (net_result == net::OK) ? PP_OK : PP_ERROR_FAILED; 191 return (net_result == net::OK) ? PP_OK : PP_ERROR_FAILED;
160 } 192 }
193 case PP_UDPSOCKET_OPTION_MULTICAST_TTL: {
194 int32_t integer_value = 0;
195 if (!value.GetInt32(&integer_value) ||
196 integer_value < 0 || integer_value > 255)
197 return PP_ERROR_BADARGUMENT;
198
199 multicast_time_to_live_ = integer_value;
200 return PP_OK;
201 }
202 case PP_UDPSOCKET_OPTION_MULTICAST_JOIN:
203 case PP_UDPSOCKET_OPTION_MULTICAST_LEAVE: {
204 PP_Resource resource = 0;
205 if (!value.GetInt32(&resource))
206 return PP_ERROR_BADARGUMENT;
207
208 EnterResource<PPB_NetAddress_API> net_address_api(resource, true);
209 if (net_address_api.failed())
210 return PP_ERROR_BADRESOURCE;
211
212 PP_NetAddress_Private addr;
213 PP_NetAddress_Family family = net_address_api.object()->GetFamily();
214 if (family == PP_NETADDRESS_FAMILY_IPV6) {
215 PP_NetAddress_IPv4 v4;
216 if (!net_address_api.object()->DescribeAsIPv4Address(&v4))
217 return PP_ERROR_ADDRESS_INVALID;
218 NetAddressPrivateImpl::CreateNetAddressPrivateFromIPv4Address(
219 v4, &addr);
220 }
221 else if (family == PP_NETADDRESS_FAMILY_IPV6) {
ygorshenin1 2014/11/14 08:03:43 nit: joint lines #220 and #221.
etrunko 2014/11/17 17:45:10 Done.
222 PP_NetAddress_IPv6 v6;
223 if (!net_address_api.object()->DescribeAsIPv6Address(&v6))
224 return PP_ERROR_ADDRESS_INVALID;
225 NetAddressPrivateImpl::CreateNetAddressPrivateFromIPv6Address(
226 v6, &addr);
227 }
228 else
ygorshenin1 2014/11/14 08:03:43 nit: join lines #228 and #227 and wrap return stat
etrunko 2014/11/17 17:45:09 Done.
229 return PP_ERROR_BADARGUMENT;
230
231 net::IPAddressNumber group;
232 int port;
233 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port))
234 return PP_ERROR_ADDRESS_INVALID;
235
236 int net_result = net::ERR_UNEXPECTED;
237 if (name == PP_UDPSOCKET_OPTION_MULTICAST_JOIN)
238 net_result = socket_->JoinGroup(group);
239 else if (name == PP_UDPSOCKET_OPTION_MULTICAST_LEAVE)
240 net_result = socket_->LeaveGroup(group);
241 return (net_result == net::OK) ? PP_OK : PP_ERROR_FAILED;
242 }
161 default: { 243 default: {
162 NOTREACHED(); 244 NOTREACHED();
163 return PP_ERROR_BADARGUMENT; 245 return PP_ERROR_BADARGUMENT;
164 } 246 }
165 } 247 }
166 } 248 }
167 249
168 int32_t PepperUDPSocketMessageFilter::OnMsgBind( 250 int32_t PepperUDPSocketMessageFilter::OnMsgBind(
169 const ppapi::host::HostMessageContext* context, 251 const ppapi::host::HostMessageContext* context,
170 const PP_NetAddress_Private& addr) { 252 const PP_NetAddress_Private& addr) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 int port; 342 int port;
261 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) { 343 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
262 SendBindError(context, PP_ERROR_ADDRESS_INVALID); 344 SendBindError(context, PP_ERROR_ADDRESS_INVALID);
263 return; 345 return;
264 } 346 }
265 347
266 if (allow_address_reuse_) 348 if (allow_address_reuse_)
267 socket->AllowAddressReuse(); 349 socket->AllowAddressReuse();
268 if (allow_broadcast_) 350 if (allow_broadcast_)
269 socket->AllowBroadcast(); 351 socket->AllowBroadcast();
352 if (multicast_loop_)
353 socket->SetMulticastLoopbackMode(multicast_loop_);
354 if (multicast_interface_)
355 socket->SetMulticastInterface(multicast_interface_);
356 if (multicast_time_to_live_)
357 socket->SetMulticastTimeToLive(multicast_time_to_live_);
270 358
271 int32_t pp_result = 359 int32_t pp_result =
272 NetErrorToPepperError(socket->Listen(net::IPEndPoint(address, port))); 360 NetErrorToPepperError(socket->Listen(net::IPEndPoint(address, port)));
273 if (pp_result != PP_OK) { 361 if (pp_result != PP_OK) {
274 SendBindError(context, pp_result); 362 SendBindError(context, pp_result);
275 return; 363 return;
276 } 364 }
277 365
278 net::IPEndPoint bound_address; 366 net::IPEndPoint bound_address;
279 pp_result = NetErrorToPepperError(socket->GetLocalAddress(&bound_address)); 367 pp_result = NetErrorToPepperError(socket->GetLocalAddress(&bound_address));
280 if (pp_result != PP_OK) { 368 if (pp_result != PP_OK) {
281 SendBindError(context, pp_result); 369 SendBindError(context, pp_result);
282 return; 370 return;
283 } 371 }
284 372
285 PP_NetAddress_Private net_address = NetAddressPrivateImpl::kInvalidNetAddress; 373 PP_NetAddress_Private net_address = NetAddressPrivateImpl::kInvalidNetAddress;
286 if (!NetAddressPrivateImpl::IPEndPointToNetAddress( 374 if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
287 bound_address.address(), bound_address.port(), &net_address)) { 375 bound_address.address(), bound_address.port(), &net_address)) {
288 SendBindError(context, PP_ERROR_ADDRESS_INVALID); 376 SendBindError(context, PP_ERROR_ADDRESS_INVALID);
289 return; 377 return;
290 } 378 }
291 379
292 allow_address_reuse_ = false; 380 allow_address_reuse_ = false;
293 allow_broadcast_ = false; 381 allow_broadcast_ = false;
382 multicast_loop_ = false;
383 multicast_interface_ = 0;
384 multicast_time_to_live_ = 0;
294 socket_.swap(socket); 385 socket_.swap(socket);
295 SendBindReply(context, PP_OK, net_address); 386 SendBindReply(context, PP_OK, net_address);
296 387
297 DoRecvFrom(); 388 DoRecvFrom();
298 } 389 }
299 390
300 void PepperUDPSocketMessageFilter::DoRecvFrom() { 391 void PepperUDPSocketMessageFilter::DoRecvFrom() {
301 DCHECK_CURRENTLY_ON(BrowserThread::IO); 392 DCHECK_CURRENTLY_ON(BrowserThread::IO);
302 DCHECK(!closed_); 393 DCHECK(!closed_);
303 DCHECK(socket_.get()); 394 DCHECK(socket_.get());
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 NetAddressPrivateImpl::kInvalidNetAddress); 556 NetAddressPrivateImpl::kInvalidNetAddress);
466 } 557 }
467 558
468 void PepperUDPSocketMessageFilter::SendSendToError( 559 void PepperUDPSocketMessageFilter::SendSendToError(
469 const ppapi::host::ReplyMessageContext& context, 560 const ppapi::host::ReplyMessageContext& context,
470 int32_t result) { 561 int32_t result) {
471 SendSendToReply(context, result, 0); 562 SendSendToReply(context, result, 0);
472 } 563 }
473 564
474 } // namespace content 565 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698