[M108 Aura Migration][NaCl][PPFwk] Add error logs + SVACE/DLOG/Static analysis fix
[platform/framework/web/chromium-efl.git] / content / browser / renderer_host / pepper / pepper_tcp_socket_message_filter.cc
1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h"
6
7 #include <cstring>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h"
15 #include "build/build_config.h"
16 #include "build/chromeos_buildflags.h"
17 #include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h"
18 #include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
19 #include "content/public/browser/browser_context.h"
20 #include "content/public/browser/browser_task_traits.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/render_frame_host.h"
23 #include "content/public/browser/render_process_host.h"
24 #include "content/public/browser/storage_partition.h"
25 #include "content/public/common/socket_permission_request.h"
26 #include "mojo/public/cpp/bindings/callback_helpers.h"
27 #include "mojo/public/cpp/bindings/pending_remote.h"
28 #include "net/base/address_family.h"
29 #include "net/base/host_port_pair.h"
30 #include "net/base/io_buffer.h"
31 #include "net/base/ip_address.h"
32 #include "net/base/net_errors.h"
33 #include "net/base/network_isolation_key.h"
34 #include "net/dns/public/resolve_error_info.h"
35 #include "net/log/net_log_source.h"
36 #include "net/log/net_log_with_source.h"
37 #include "net/ssl/ssl_info.h"
38 #include "net/traffic_annotation/network_traffic_annotation.h"
39 #include "ppapi/host/dispatch_host_message.h"
40 #include "ppapi/host/error_conversion.h"
41 #include "ppapi/host/ppapi_host.h"
42 #include "ppapi/host/resource_host.h"
43 #include "ppapi/proxy/ppapi_messages.h"
44 #include "ppapi/proxy/tcp_socket_resource_constants.h"
45 #include "ppapi/shared_impl/private/net_address_private_impl.h"
46 #include "ppapi/shared_impl/private/ppb_x509_util_shared.h"
47
48 #if BUILDFLAG(IS_CHROMEOS_ASH)
49 #include "chromeos/ash/components/network/firewall_hole.h"
50 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
51
52 using ppapi::NetAddressPrivateImpl;
53 using ppapi::TCPSocketState;
54 using ppapi::TCPSocketVersion;
55 using ppapi::host::NetErrorToPepperError;
56 using ppapi::proxy::TCPSocketResourceConstants;
57
58 namespace {
59
60 size_t g_num_tcp_filter_instances = 0;
61
62 }  // namespace
63
64 namespace content {
65
66 network::mojom::NetworkContext*
67     PepperTCPSocketMessageFilter::network_context_for_testing = nullptr;
68
69 PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter(
70     ContentBrowserPepperHostFactory* factory,
71     BrowserPpapiHostImpl* host,
72     PP_Instance instance,
73     TCPSocketVersion version)
74     : version_(version),
75       host_(host),
76       factory_(factory),
77       instance_(instance),
78       external_plugin_(host->external_plugin()),
79       render_process_id_(0),
80       render_frame_id_(0),
81       state_(TCPSocketState::INITIAL),
82       bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress),
83       socket_options_(SOCKET_OPTION_NODELAY),
84       rcvbuf_size_(0),
85       sndbuf_size_(0),
86       pending_accept_(false),
87       pending_read_size_(0),
88       pending_read_pp_error_(PP_OK_COMPLETIONPENDING),
89       pending_write_bytes_written_(0),
90       pending_write_pp_error_(PP_OK_COMPLETIONPENDING),
91       is_potentially_secure_plugin_context_(
92           host->IsPotentiallySecurePluginContext(instance)) {
93   DCHECK(host);
94   DCHECK_CURRENTLY_ON(BrowserThread::UI);
95
96   ++g_num_tcp_filter_instances;
97   host_->AddInstanceObserver(instance_, this);
98   if (!host->GetRenderFrameIDsForInstance(instance, &render_process_id_,
99                                           &render_frame_id_)) {
100     NOTREACHED();
101   }
102 }
103
104 void PepperTCPSocketMessageFilter::SetConnectedSocket(
105     mojo::PendingRemote<network::mojom::TCPConnectedSocket> connected_socket,
106     mojo::PendingReceiver<network::mojom::SocketObserver>
107         socket_observer_receiver,
108     mojo::ScopedDataPipeConsumerHandle receive_stream,
109     mojo::ScopedDataPipeProducerHandle send_stream) {
110   DCHECK_CURRENTLY_ON(BrowserThread::UI);
111   // This method grabs a reference to |this|, and releases a reference on the UI
112   // thread, so something should be holding on to a reference on the current
113   // thread to prevent the object from being deleted before this method returns.
114   DCHECK(HasOneRef());
115
116   GetUIThreadTaskRunner({})->PostTask(
117       FROM_HERE,
118       base::BindOnce(
119           &PepperTCPSocketMessageFilter::SetConnectedSocketOnUIThread, this,
120           std::move(connected_socket), std::move(socket_observer_receiver),
121           std::move(receive_stream), std::move(send_stream)));
122 }
123
124 PepperTCPSocketMessageFilter::~PepperTCPSocketMessageFilter() {
125   DCHECK_CURRENTLY_ON(BrowserThread::UI);
126   if (host_)
127     host_->RemoveInstanceObserver(instance_, this);
128 #if BUILDFLAG(IS_CHROMEOS_ASH)
129   // Close the firewall hole on UI thread if there is one.
130   if (firewall_hole_) {
131     GetUIThreadTaskRunner({})->DeleteSoon(FROM_HERE, std::move(firewall_hole_));
132   }
133 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
134   --g_num_tcp_filter_instances;
135 }
136
137 void PepperTCPSocketMessageFilter::SetConnectedSocketOnUIThread(
138     mojo::PendingRemote<network::mojom::TCPConnectedSocket> connected_socket,
139     mojo::PendingReceiver<network::mojom::SocketObserver>
140         socket_observer_receiver,
141     mojo::ScopedDataPipeConsumerHandle receive_stream,
142     mojo::ScopedDataPipeProducerHandle send_stream) {
143   DCHECK_CURRENTLY_ON(BrowserThread::UI);
144   DCHECK_EQ(state_.state(), TCPSocketState::INITIAL);
145
146   state_ = TCPSocketState(TCPSocketState::CONNECTED);
147   connected_socket_.Bind(std::move(connected_socket));
148   socket_observer_receiver_.Bind(std::move(socket_observer_receiver));
149   socket_observer_receiver_.set_disconnect_handler(
150       base::BindOnce(&PepperTCPSocketMessageFilter::OnSocketObserverError,
151                      base::Unretained(this)));
152
153   SetStreams(std::move(receive_stream), std::move(send_stream));
154 }
155
156 // static
157 void PepperTCPSocketMessageFilter::SetNetworkContextForTesting(
158     network::mojom::NetworkContext* network_context) {
159   network_context_for_testing = network_context;
160 }
161
162 // static
163 size_t PepperTCPSocketMessageFilter::GetNumInstances() {
164   return g_num_tcp_filter_instances;
165 }
166
167 void PepperTCPSocketMessageFilter::OnFilterDestroyed() {
168   ResourceMessageFilter::OnFilterDestroyed();
169   // Need to close all mojo pipes the socket on the UI thread. Calling Close()
170   // also ensures that future messages will be ignored, so the mojo pipes won't
171   // be re-created, so after Close() runs, |this| can be safely deleted on the
172   // IO thread.
173   GetUIThreadTaskRunner({})->PostTask(
174       FROM_HERE, base::BindOnce(&PepperTCPSocketMessageFilter::Close, this));
175 }
176
177 scoped_refptr<base::SequencedTaskRunner>
178 PepperTCPSocketMessageFilter::OverrideTaskRunnerForMessage(
179     const IPC::Message& message) {
180   switch (message.type()) {
181     case PpapiHostMsg_TCPSocket_Bind::ID:
182     case PpapiHostMsg_TCPSocket_Connect::ID:
183     case PpapiHostMsg_TCPSocket_ConnectWithNetAddress::ID:
184     case PpapiHostMsg_TCPSocket_Listen::ID:
185     case PpapiHostMsg_TCPSocket_SSLHandshake::ID:
186     case PpapiHostMsg_TCPSocket_Read::ID:
187     case PpapiHostMsg_TCPSocket_Write::ID:
188     case PpapiHostMsg_TCPSocket_Accept::ID:
189     case PpapiHostMsg_TCPSocket_Close::ID:
190     case PpapiHostMsg_TCPSocket_SetOption::ID:
191       return GetUIThreadTaskRunner({});
192   }
193   return nullptr;
194 }
195
196 int32_t PepperTCPSocketMessageFilter::OnResourceMessageReceived(
197     const IPC::Message& msg,
198     ppapi::host::HostMessageContext* context) {
199   PPAPI_BEGIN_MESSAGE_MAP(PepperTCPSocketMessageFilter, msg)
200     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Bind, OnMsgBind)
201     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Connect,
202                                       OnMsgConnect)
203     PPAPI_DISPATCH_HOST_RESOURCE_CALL(
204         PpapiHostMsg_TCPSocket_ConnectWithNetAddress,
205         OnMsgConnectWithNetAddress)
206     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_SSLHandshake,
207                                       OnMsgSSLHandshake)
208     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Read, OnMsgRead)
209     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Write, OnMsgWrite)
210     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Listen,
211                                       OnMsgListen)
212     PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_TCPSocket_Accept,
213                                         OnMsgAccept)
214     PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_TCPSocket_Close,
215                                         OnMsgClose)
216     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_SetOption,
217                                       OnMsgSetOption)
218   PPAPI_END_MESSAGE_MAP()
219   LOG(ERROR) << "Resource message unresolved";
220   return PP_ERROR_FAILED;
221 }
222
223 void PepperTCPSocketMessageFilter::OnHostDestroyed() {
224   DCHECK_CURRENTLY_ON(BrowserThread::UI);
225   host_->RemoveInstanceObserver(instance_, this);
226   host_ = nullptr;
227 }
228
229 void PepperTCPSocketMessageFilter::OnComplete(
230     int result,
231     const net::ResolveErrorInfo& resolve_error_info,
232     const absl::optional<net::AddressList>& resolved_addresses,
233     const absl::optional<net::HostResolverEndpointResults>&
234         endpoint_results_with_metadata) {
235   DCHECK_CURRENTLY_ON(BrowserThread::UI);
236   receiver_.reset();
237
238   if (!host_resolve_context_.is_valid())
239     return;
240
241   ppapi::host::ReplyMessageContext context = host_resolve_context_;
242   host_resolve_context_ = ppapi::host::ReplyMessageContext();
243
244   if (!state_.IsPending(TCPSocketState::CONNECT)) {
245     DCHECK(state_.state() == TCPSocketState::CLOSED);
246     SendConnectError(context, PP_ERROR_FAILED);
247     return;
248   }
249
250   if (result != net::OK) {
251     SendConnectError(context, NetErrorToPepperError(resolve_error_info.error));
252     state_.CompletePendingTransition(false);
253     return;
254   }
255
256   StartConnect(context, resolved_addresses.value());
257 }
258
259 void PepperTCPSocketMessageFilter::OnReadError(int net_error) {
260   // If this method is called more than once, or |net_error| isn't an allowed
261   // value, just ignore the message.
262   if (pending_read_pp_error_ != PP_OK_COMPLETIONPENDING || net_error > 0 ||
263       net_error == net::ERR_IO_PENDING) {
264     return;
265   }
266
267   pending_read_pp_error_ = NetErrorToPepperError(net_error);
268   // Complete pending read with the error message if there's a pending read, and
269   // the read data pipe has already been closed. If the pipe is still open, need
270   // to wait until all data has been read before can start failing reads.
271   if (pending_read_context_.is_valid() && !receive_stream_) {
272     TryRead();
273   }
274 }
275
276 void PepperTCPSocketMessageFilter::OnWriteError(int net_error) {
277   // If this method is called more than once, or |net_error| isn't an allowed
278   // value, just ignore the message.
279   if (pending_write_pp_error_ != PP_OK_COMPLETIONPENDING || net_error > 0 ||
280       net_error == net::ERR_IO_PENDING) {
281     return;
282   }
283
284   pending_write_pp_error_ = NetErrorToPepperError(net_error);
285   // Complete pending write with the error message if there's a pending write,
286   // and the write data pipe has already been closed.
287   if (pending_write_context_.is_valid() && !send_stream_)
288     TryWrite();
289 }
290
291 void PepperTCPSocketMessageFilter::OnSocketObserverError() {
292   // Note that this method may be called while a connection is still being made.
293   socket_observer_receiver_.reset();
294
295   // Treat this as a read and write error. If read and write errors have already
296   // been received, these calls will do nothing.
297   OnReadError(PP_ERROR_FAILED);
298   OnWriteError(PP_ERROR_FAILED);
299 }
300
301 int32_t PepperTCPSocketMessageFilter::OnMsgBind(
302     const ppapi::host::HostMessageContext* context,
303     const PP_NetAddress_Private& net_addr) {
304   DCHECK_CURRENTLY_ON(BrowserThread::UI);
305
306   // This is only supported by PPB_TCPSocket v1.1 or above.
307   if (version_ != ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) {
308     LOG(ERROR) << "Supported only by PPB_TCPSocket v1.1 or above";
309     NOTREACHED();
310     return PP_ERROR_NOACCESS;
311   }
312
313   if (!pepper_socket_utils::CanUseSocketAPIs(
314           external_plugin_, false /* private_api */, nullptr,
315           render_process_id_, render_frame_id_)) {
316     LOG(ERROR) << "Cannot use Socket APIs";
317     return PP_ERROR_NOACCESS;
318   }
319
320   if (state_.IsPending(TCPSocketState::BIND))
321     return PP_ERROR_INPROGRESS;
322
323   if (!state_.IsValidTransition(TCPSocketState::BIND))
324     return PP_ERROR_FAILED;
325
326   DCHECK(!bound_socket_);
327   DCHECK(!connected_socket_);
328   DCHECK(!server_socket_);
329
330   // Validate address.
331   net::IPAddressBytes address;
332   uint16_t port;
333   if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(net_addr, &address,
334                                                      &port)) {
335     state_.DoTransition(TCPSocketState::BIND, false);
336     return PP_ERROR_ADDRESS_INVALID;
337   }
338
339   network::mojom::NetworkContext* network_context = GetNetworkContext();
340   if (!network_context)
341     return PP_ERROR_FAILED;
342
343   // The network service doesn't allow binding a socket without first
344   // specifying if it's going to be used as a read or write socket,
345   // so just hold onto the address for now, without actually binding anything.
346   bind_input_addr_ = net_addr;
347
348   state_.SetPendingTransition(TCPSocketState::BIND);
349   network_context->CreateTCPBoundSocket(
350       net::IPEndPoint(net::IPAddress(address), port),
351       pepper_socket_utils::PepperTCPNetworkAnnotationTag(),
352       bound_socket_.BindNewPipeAndPassReceiver(),
353       mojo::WrapCallbackWithDefaultInvokeIfNotRun(
354           base::BindOnce(&PepperTCPSocketMessageFilter::OnBindCompleted,
355                          weak_ptr_factory_.GetWeakPtr(),
356                          context->MakeReplyMessageContext()),
357           net::ERR_FAILED, absl::nullopt /* local_addr */));
358
359   return PP_OK_COMPLETIONPENDING;
360 }
361
362 int32_t PepperTCPSocketMessageFilter::OnMsgConnect(
363     const ppapi::host::HostMessageContext* context,
364     const std::string& host,
365     uint16_t port) {
366   DCHECK_CURRENTLY_ON(BrowserThread::UI);
367
368   // This is only supported by PPB_TCPSocket_Private.
369   if (!IsPrivateAPI()) {
370     NOTREACHED();
371     LOG(ERROR) << "Supported only by PPB_TCPSocket_Private";
372     return PP_ERROR_NOACCESS;
373   }
374
375   SocketPermissionRequest request(SocketPermissionRequest::TCP_CONNECT, host,
376                                   port);
377   if (!pepper_socket_utils::CanUseSocketAPIs(
378           external_plugin_, true /* private_api */, &request,
379           render_process_id_, render_frame_id_)) {
380     LOG(ERROR) << "Insufficient permissions";
381     return PP_ERROR_NOACCESS;
382   }
383
384   if (!state_.IsValidTransition(TCPSocketState::CONNECT)) {
385     NOTREACHED() << "This shouldn't be reached since the renderer only tries "
386                  << "to connect once.";
387     return PP_ERROR_FAILED;
388   }
389
390   network::mojom::NetworkContext* network_context = GetNetworkContext();
391   if (!network_context)
392     return PP_ERROR_FAILED;
393
394   RenderFrameHost* render_frame_host =
395       RenderFrameHost::FromID(render_process_id_, render_frame_id_);
396   if (!render_frame_host)
397     return PP_ERROR_FAILED;
398
399   // Intentionally using a HostPortPair because scheme isn't specified.
400   // TODO(mmenke): Pass in correct NetworkAnonymizationKey.
401   network_context->ResolveHost(
402       network::mojom::HostResolverHost::NewHostPortPair(
403           net::HostPortPair(host, port)),
404       render_frame_host->GetIsolationInfoForSubresources()
405           .network_anonymization_key(),
406       nullptr, receiver_.BindNewPipeAndPassRemote());
407   receiver_.set_disconnect_handler(base::BindOnce(
408       &PepperTCPSocketMessageFilter::OnComplete, base::Unretained(this),
409       net::ERR_NAME_NOT_RESOLVED, net::ResolveErrorInfo(net::ERR_FAILED),
410       /*resolved_addresses=*/absl::nullopt,
411       /*endpoint_results_with_metadata=*/absl::nullopt));
412
413   state_.SetPendingTransition(TCPSocketState::CONNECT);
414   host_resolve_context_ = context->MakeReplyMessageContext();
415   return PP_OK_COMPLETIONPENDING;
416 }
417
418 int32_t PepperTCPSocketMessageFilter::OnMsgConnectWithNetAddress(
419     const ppapi::host::HostMessageContext* context,
420     const PP_NetAddress_Private& net_addr) {
421   DCHECK_CURRENTLY_ON(BrowserThread::UI);
422
423   SocketPermissionRequest request =
424       pepper_socket_utils::CreateSocketPermissionRequest(
425           SocketPermissionRequest::TCP_CONNECT, net_addr);
426   if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, IsPrivateAPI(),
427                                              &request, render_process_id_,
428                                              render_frame_id_)) {
429     LOG(ERROR) << "Insufficient permissions: Cannot connect with NetAddress";
430     return PP_ERROR_NOACCESS;
431   }
432
433   if (!state_.IsValidTransition(TCPSocketState::CONNECT))
434     return PP_ERROR_FAILED;
435
436   state_.SetPendingTransition(TCPSocketState::CONNECT);
437
438   net::IPAddressBytes address;
439   uint16_t port;
440   if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(net_addr, &address,
441                                                      &port)) {
442     state_.CompletePendingTransition(false);
443     return PP_ERROR_ADDRESS_INVALID;
444   }
445
446   StartConnect(
447       context->MakeReplyMessageContext(),
448       net::AddressList(net::IPEndPoint(net::IPAddress(address), port)));
449   return PP_OK_COMPLETIONPENDING;
450 }
451
452 int32_t PepperTCPSocketMessageFilter::OnMsgSSLHandshake(
453     const ppapi::host::HostMessageContext* context,
454     const std::string& server_name,
455     uint16_t server_port,
456     const std::vector<std::vector<char>>& trusted_certs,
457     const std::vector<std::vector<char>>& untrusted_certs) {
458   DCHECK_CURRENTLY_ON(BrowserThread::UI);
459
460   // Allow to do SSL handshake only if currently the socket has been connected
461   // and there isn't pending read or write.
462   if (!state_.IsValidTransition(TCPSocketState::SSL_CONNECT) ||
463       pending_read_context_.is_valid() || pending_write_context_.is_valid()) {
464     LOG(ERROR) << "Socket not connected or pending read or write";
465     return PP_ERROR_FAILED;
466   }
467
468   // If there's a pending read or write error, fail the request with that.
469   if (pending_read_pp_error_ != PP_OK_COMPLETIONPENDING) {
470     if (pending_read_pp_error_ == PP_OK)
471       pending_read_pp_error_ = PP_ERROR_FAILED;
472     return pending_read_pp_error_;
473   }
474
475   if (pending_write_pp_error_ != PP_OK_COMPLETIONPENDING) {
476     if (pending_write_pp_error_ == PP_OK)
477       pending_write_pp_error_ = PP_ERROR_FAILED;
478     return pending_write_pp_error_;
479   }
480
481   // TODO(raymes,rsleevi): Use trusted/untrusted certificates when connecting.
482
483   // Close all Mojo pipes except |connected_socket_|.
484   receive_stream_.reset();
485   read_watcher_.reset();
486   send_stream_.reset();
487   write_watcher_.reset();
488   socket_observer_receiver_.reset();
489
490   state_.SetPendingTransition(TCPSocketState::SSL_CONNECT);
491
492   network::mojom::TLSClientSocketOptionsPtr tls_client_socket_options =
493       network::mojom::TLSClientSocketOptions::New();
494   tls_client_socket_options->send_ssl_info = true;
495   net::HostPortPair host_port_pair(server_name, server_port);
496   connected_socket_->UpgradeToTLS(
497       host_port_pair, std::move(tls_client_socket_options),
498       pepper_socket_utils::PepperTCPNetworkAnnotationTag(),
499       tls_client_socket_.BindNewPipeAndPassReceiver(),
500       socket_observer_receiver_.BindNewPipeAndPassRemote(),
501       mojo::WrapCallbackWithDefaultInvokeIfNotRun(
502           base::BindOnce(&PepperTCPSocketMessageFilter::OnSSLHandshakeCompleted,
503                          base::Unretained(this),
504                          context->MakeReplyMessageContext()),
505           net::ERR_FAILED, mojo::ScopedDataPipeConsumerHandle(),
506           mojo::ScopedDataPipeProducerHandle(), absl::nullopt /* ssl_info */));
507
508   socket_observer_receiver_.set_disconnect_handler(
509       base::BindOnce(&PepperTCPSocketMessageFilter::OnSocketObserverError,
510                      base::Unretained(this)));
511
512   return PP_OK_COMPLETIONPENDING;
513 }
514
515 int32_t PepperTCPSocketMessageFilter::OnMsgRead(
516     const ppapi::host::HostMessageContext* context,
517     int32_t bytes_to_read) {
518   DCHECK_CURRENTLY_ON(BrowserThread::UI);
519   // This only covers the case where the socket was explicitly closed from the
520   // caller, or the filter is being destroyed. Read errors and Mojo errors are
521   // handled in TryRead().
522   if (!state_.IsConnected()) {
523     LOG(ERROR) << "Not connected";
524     return PP_ERROR_FAILED;
525   }
526   if (pending_read_context_.is_valid())
527     return PP_ERROR_INPROGRESS;
528   if (bytes_to_read <= 0 ||
529       bytes_to_read > TCPSocketResourceConstants::kMaxReadSize) {
530     LOG(ERROR) << "Incorrect number of bytes to read - " << bytes_to_read
531                << " Should be <= " << TCPSocketResourceConstants::kMaxReadSize
532                << " and > 0";
533     return PP_ERROR_BADARGUMENT;
534   }
535
536   pending_read_context_ = context->MakeReplyMessageContext();
537   pending_read_size_ = static_cast<uint32_t>(bytes_to_read);
538   TryRead();
539   return PP_OK_COMPLETIONPENDING;
540 }
541
542 int32_t PepperTCPSocketMessageFilter::OnMsgWrite(
543     const ppapi::host::HostMessageContext* context,
544     const ppapi::DataView& data) {
545   DCHECK_CURRENTLY_ON(BrowserThread::UI);
546
547   if (!state_.IsConnected()) {
548     LOG(ERROR) << "Not connected";
549     return PP_ERROR_FAILED;
550   }
551   if (pending_write_context_.is_valid())
552     return PP_ERROR_INPROGRESS;
553
554   DCHECK_EQ(0u, pending_write_data_.size);
555   DCHECK_EQ(0u, pending_write_bytes_written_);
556
557   size_t data_size = data.size;
558   if (data_size == 0 ||
559       data_size >
560           static_cast<size_t>(TCPSocketResourceConstants::kMaxWriteSize)) {
561     LOG(ERROR) << "Invalid data size - " << data_size << " should be <= "
562                << static_cast<size_t>(TCPSocketResourceConstants::kMaxWriteSize)
563                << " and != 0";
564     return PP_ERROR_BADARGUMENT;
565   }
566
567   pending_write_data_ = data;
568   pending_write_context_ = context->MakeReplyMessageContext();
569   TryWrite();
570   return PP_OK_COMPLETIONPENDING;
571 }
572
573 int32_t PepperTCPSocketMessageFilter::OnMsgListen(
574     const ppapi::host::HostMessageContext* context,
575     int32_t backlog) {
576   DCHECK_CURRENTLY_ON(BrowserThread::UI);
577
578   if (state_.IsPending(TCPSocketState::LISTEN))
579     return PP_ERROR_INPROGRESS;
580
581   if (!state_.IsValidTransition(TCPSocketState::LISTEN))
582     return PP_ERROR_FAILED;
583
584   // This is only supported by PPB_TCPSocket v1.1 or above.
585   if (version_ != ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) {
586     LOG(ERROR) << "Supported only by PPB_TCPSocket v1.1 or above";
587     NOTREACHED();
588     return PP_ERROR_NOACCESS;
589   }
590
591   SocketPermissionRequest request =
592       pepper_socket_utils::CreateSocketPermissionRequest(
593           SocketPermissionRequest::TCP_LISTEN, bind_input_addr_);
594   if (!pepper_socket_utils::CanUseSocketAPIs(
595           external_plugin_, false /* private_api */, &request,
596           render_process_id_, render_frame_id_)) {
597     LOG(ERROR) << "Insufficient permissions";
598     return PP_ERROR_NOACCESS;
599   }
600
601   DCHECK(bound_socket_);
602   DCHECK(!server_socket_);
603
604   state_.SetPendingTransition(TCPSocketState::LISTEN);
605
606   bound_socket_->Listen(
607       backlog, server_socket_.BindNewPipeAndPassReceiver(),
608       mojo::WrapCallbackWithDefaultInvokeIfNotRun(
609           base::BindOnce(&PepperTCPSocketMessageFilter::OnListenCompleted,
610                          base::Unretained(this),
611                          context->MakeReplyMessageContext()),
612           net::ERR_FAILED));
613   return PP_OK_COMPLETIONPENDING;
614 }
615
616 int32_t PepperTCPSocketMessageFilter::OnMsgAccept(
617     const ppapi::host::HostMessageContext* context) {
618   DCHECK_CURRENTLY_ON(BrowserThread::UI);
619
620   if (pending_accept_) {
621     LOG(WARNING) << "Pending accept";
622     return PP_ERROR_INPROGRESS;
623   }
624   if (state_.state() != TCPSocketState::LISTENING) {
625     LOG(ERROR) << "Invalid socket state: " << static_cast<int>(state_.state());
626     return PP_ERROR_FAILED;
627   }
628   DCHECK(server_socket_);
629
630   pending_accept_ = true;
631
632   mojo::PendingRemote<network::mojom::SocketObserver> socket_observer;
633   auto socket_observer_receiver =
634       socket_observer.InitWithNewPipeAndPassReceiver();
635   server_socket_->Accept(
636       std::move(socket_observer),
637       mojo::WrapCallbackWithDefaultInvokeIfNotRun(
638           base::BindOnce(&PepperTCPSocketMessageFilter::OnAcceptCompleted,
639                          base::Unretained(this),
640                          context->MakeReplyMessageContext(),
641                          std::move(socket_observer_receiver)),
642           net::ERR_FAILED, absl::nullopt /* remote_addr */, mojo::NullRemote(),
643           mojo::ScopedDataPipeConsumerHandle(),
644           mojo::ScopedDataPipeProducerHandle()));
645   return PP_OK_COMPLETIONPENDING;
646 }
647
648 int32_t PepperTCPSocketMessageFilter::OnMsgClose(
649     const ppapi::host::HostMessageContext* context) {
650   DCHECK_CURRENTLY_ON(BrowserThread::UI);
651   if (state_.state() == TCPSocketState::CLOSED)
652     return PP_OK;
653
654   Close();
655   return PP_OK;
656 }
657
658 int32_t PepperTCPSocketMessageFilter::OnMsgSetOption(
659     const ppapi::host::HostMessageContext* context,
660     PP_TCPSocket_Option name,
661     const ppapi::SocketOptionData& value) {
662   DCHECK_CURRENTLY_ON(BrowserThread::UI);
663
664   // Options are only applied if |this| is currently being used as a client
665   // socket, or is going to be used as one - they are ignored for server
666   // sockets.
667   switch (name) {
668     case PP_TCPSOCKET_OPTION_NO_DELAY: {
669       bool boolean_value = false;
670       if (!value.GetBool(&boolean_value)) {
671         LOG(ERROR) << "Invalid socket option";
672         return PP_ERROR_BADARGUMENT;
673       }
674       // If |connected_socket_| is connecting or has connected, pass the setting
675       // along.
676       if (connected_socket_.is_bound()) {
677         connected_socket_->SetNoDelay(
678             boolean_value,
679             // Callback that converts a bool to a net error code which it then
680             // passes to the common completion callback routine.
681             base::BindOnce(
682                 [](base::OnceCallback<void(int)> completion_callback,
683                    bool success) {
684                   std::move(completion_callback)
685                       .Run(success ? net::OK : net::ERR_FAILED);
686                 },
687                 CreateCompletionCallback<
688                     PpapiPluginMsg_TCPSocket_SetOptionReply>(context)));
689         return PP_OK_COMPLETIONPENDING;
690       }
691
692       // TCPConnectedSocket instance is not yet created. So remember the value
693       // here.
694       if (boolean_value) {
695         socket_options_ |= SOCKET_OPTION_NODELAY;
696       } else {
697         socket_options_ &= ~SOCKET_OPTION_NODELAY;
698       }
699       return PP_OK;
700     }
701     case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: {
702       int32_t integer_value = 0;
703       if (!value.GetInt32(&integer_value) || integer_value <= 0 ||
704           integer_value > TCPSocketResourceConstants::kMaxSendBufferSize) {
705         LOG(ERROR) << "Invalid send buffer size value - " << integer_value
706                    << " should be <= "
707                    << TCPSocketResourceConstants::kMaxSendBufferSize
708                    << " and > 0";
709         return PP_ERROR_BADARGUMENT;
710       }
711
712       // If |connected_socket_| is connecting or has connected, pass the setting
713       // along.
714       if (connected_socket_.is_bound()) {
715         connected_socket_->SetSendBufferSize(
716             integer_value,
717             CreateCompletionCallback<PpapiPluginMsg_TCPSocket_SetOptionReply>(
718                 context));
719         return PP_OK_COMPLETIONPENDING;
720       }
721
722       // TCPSocket instance is not yet created. So remember the value here.
723       socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE;
724       sndbuf_size_ = integer_value;
725       return PP_OK;
726     }
727     case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: {
728       int32_t integer_value = 0;
729       if (!value.GetInt32(&integer_value) || integer_value <= 0 ||
730           integer_value > TCPSocketResourceConstants::kMaxReceiveBufferSize) {
731         LOG(ERROR) << "Invalid receive buffer size - " << integer_value
732                    << " should be <= "
733                    << TCPSocketResourceConstants::kMaxReceiveBufferSize
734                    << " and > 0";
735         return PP_ERROR_BADARGUMENT;
736       }
737
738       // If |connected_socket_| is connecting or has connected, pass the setting
739       // along.
740       if (connected_socket_.is_bound()) {
741         connected_socket_->SetReceiveBufferSize(
742             integer_value,
743             CreateCompletionCallback<PpapiPluginMsg_TCPSocket_SetOptionReply>(
744                 context));
745         return PP_OK_COMPLETIONPENDING;
746       }
747
748       // TCPConnectedSocket instance is not yet created. So remember the value
749       // here.
750       socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE;
751       rcvbuf_size_ = integer_value;
752       return PP_OK;
753     }
754     default: {
755       LOG(ERROR);
756       NOTREACHED();
757       return PP_ERROR_BADARGUMENT;
758     }
759   }
760 }
761
762 void PepperTCPSocketMessageFilter::TryRead() {
763   DCHECK_CURRENTLY_ON(BrowserThread::UI);
764   DCHECK(state_.IsConnected());
765   DCHECK(pending_read_context_.is_valid());
766   DCHECK_GT(pending_read_size_, 0u);
767
768   // This loop's body will generally run only once, unless there's a read error,
769   // in which case, it will start over, to re-apply the initial logic.
770   while (true) {
771     // As long as the read stream is still open, try to read data, even if a
772     // read error has been received from the SocketObserver, as there may still
773     // be data on the pipe.
774     if (!receive_stream_.is_valid()) {
775       // If no read error has been received yet, wait to receive one through
776       // the SocketObserver interface.
777       if (pending_read_pp_error_ == PP_OK_COMPLETIONPENDING) {
778         DCHECK(socket_observer_receiver_.is_bound());
779         break;
780       }
781
782       // Otherwise, pass along the read error.
783       SendReadError(pending_read_pp_error_);
784       // If the socket was closed gracefully, only return OK for a single
785       // read.
786       if (pending_read_pp_error_ == PP_OK)
787         pending_read_pp_error_ = PP_ERROR_FAILED;
788       break;
789     }
790
791     DCHECK(read_watcher_);
792     const void* buffer = nullptr;
793     uint32_t num_bytes = 0;
794     int mojo_result = receive_stream_->BeginReadData(&buffer, &num_bytes,
795                                                      MOJO_READ_DATA_FLAG_NONE);
796     if (mojo_result == MOJO_RESULT_SHOULD_WAIT) {
797       read_watcher_->ArmOrNotify();
798       break;
799     }
800
801     // On a Mojo pipe error (which may indicate a graceful close, network error,
802     // or network service crash), close read pipe and restart the loop.
803     if (mojo_result != MOJO_RESULT_OK) {
804       read_watcher_.reset();
805       receive_stream_.reset();
806       continue;
807     }
808
809     // This is guaranteed by Mojo.
810     DCHECK_GT(num_bytes, 0u);
811
812     uint32_t bytes_to_copy = std::min(num_bytes, pending_read_size_);
813     SendReadReply(PP_OK, ppapi::DataView(reinterpret_cast<const char*>(buffer),
814                                          bytes_to_copy));
815     receive_stream_->EndReadData(bytes_to_copy);
816     break;
817   }
818 }
819
820 void PepperTCPSocketMessageFilter::TryWrite() {
821   DCHECK_CURRENTLY_ON(BrowserThread::UI);
822   DCHECK(state_.IsConnected());
823   DCHECK(pending_write_context_.is_valid());
824   DCHECK_NE(pending_write_data_.size, 0u);
825   DCHECK_LT(pending_write_bytes_written_, pending_write_data_.size);
826
827   // The structure of this code largely mirrors TryRead() above, with a couple
828   // differences. The loop will repeat until all bytes are written, there's an
829   // error, or no more buffer space is available. Also, it's possible for a
830   // Mojo write to succeed, but a write to the underlying socket to fail. In
831   // that case, the failure might not be returned to the caller until it tries
832   // to write again. Since the socket APIs themselves don't guarantee that
833   // data has been successfully received by the remote server on success, this
834   // should not cause unexpected problems for consumers.
835   while (true) {
836     if (!send_stream_.is_valid()) {
837       if (pending_write_pp_error_ == PP_OK_COMPLETIONPENDING) {
838         DCHECK(socket_observer_receiver_.is_bound());
839         break;
840       }
841       SendWriteReply(pending_write_pp_error_);
842       // Mirror handling of "OK" read errors, only sending "OK" for a single
843       // write, though getting "OK" from a write is probably nonsense, anyways.
844       if (pending_write_pp_error_ == PP_OK)
845         pending_write_pp_error_ = PP_ERROR_FAILED;
846       break;
847     }
848
849     DCHECK(write_watcher_);
850
851     uint32_t num_bytes =
852         pending_write_data_.size - pending_write_bytes_written_;
853     DCHECK_GT(num_bytes, 0u);
854     int mojo_result = send_stream_->WriteData(
855         pending_write_data_.data + pending_write_bytes_written_, &num_bytes,
856         MOJO_WRITE_DATA_FLAG_NONE);
857     if (mojo_result == MOJO_RESULT_SHOULD_WAIT) {
858       write_watcher_->ArmOrNotify();
859       break;
860     }
861
862     // On a Mojo pipe error (which may indicate a graceful close, network error,
863     // or network service crash), close write pipe and restart the loop.
864     if (mojo_result != MOJO_RESULT_OK) {
865       write_watcher_.reset();
866       send_stream_.reset();
867       continue;
868     }
869
870     // This is guaranteed by Mojo.
871     DCHECK_GT(num_bytes, 0u);
872
873     pending_write_bytes_written_ += num_bytes;
874     // If all bytes were written, nothing left to do.
875     if (pending_write_bytes_written_ == pending_write_data_.size) {
876       SendWriteReply(pending_write_bytes_written_);
877       break;
878     }
879   }
880 }
881
882 void PepperTCPSocketMessageFilter::StartConnect(
883     const ppapi::host::ReplyMessageContext& context,
884     const net::AddressList& address_list) {
885   DCHECK_CURRENTLY_ON(BrowserThread::UI);
886   DCHECK(state_.IsPending(TCPSocketState::CONNECT));
887   DCHECK(!address_list.empty());
888
889   auto socket_observer = socket_observer_receiver_.BindNewPipeAndPassRemote();
890   socket_observer_receiver_.set_disconnect_handler(
891       base::BindOnce(&PepperTCPSocketMessageFilter::OnSocketObserverError,
892                      base::Unretained(this)));
893
894   network::mojom::TCPConnectedSocketOptionsPtr socket_options =
895       network::mojom::TCPConnectedSocketOptions::New();
896   socket_options->no_delay = !!(socket_options_ & SOCKET_OPTION_NODELAY);
897   if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE)
898     socket_options->receive_buffer_size = rcvbuf_size_;
899   if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE)
900     socket_options->send_buffer_size = sndbuf_size_;
901
902   network::mojom::NetworkContext::CreateTCPConnectedSocketCallback callback =
903       mojo::WrapCallbackWithDefaultInvokeIfNotRun(
904           base::BindOnce(&PepperTCPSocketMessageFilter::OnConnectCompleted,
905                          weak_ptr_factory_.GetWeakPtr(), context),
906           net::ERR_FAILED, absl::nullopt, absl::nullopt,
907           mojo::ScopedDataPipeConsumerHandle(),
908           mojo::ScopedDataPipeProducerHandle());
909   if (bound_socket_) {
910     bound_socket_->Connect(address_list, std::move(socket_options),
911                            connected_socket_.BindNewPipeAndPassReceiver(),
912                            std::move(socket_observer), std::move(callback));
913   } else {
914     network::mojom::NetworkContext* network_context = GetNetworkContext();
915     if (!network_context) {
916       // This will delete |callback|, which will invoke OnConnectCompleted()
917       // with an error.
918       return;
919     }
920     network_context->CreateTCPConnectedSocket(
921         absl::nullopt /* local_addr */, address_list, std::move(socket_options),
922         pepper_socket_utils::PepperTCPNetworkAnnotationTag(),
923         connected_socket_.BindNewPipeAndPassReceiver(),
924         std::move(socket_observer), std::move(callback));
925   }
926 }
927
928 void PepperTCPSocketMessageFilter::OnConnectCompleted(
929     const ppapi::host::ReplyMessageContext& context,
930     int net_result,
931     const absl::optional<net::IPEndPoint>& local_addr,
932     const absl::optional<net::IPEndPoint>& peer_addr,
933     mojo::ScopedDataPipeConsumerHandle receive_stream,
934     mojo::ScopedDataPipeProducerHandle send_stream) {
935   DCHECK_CURRENTLY_ON(BrowserThread::UI);
936
937   int32_t pp_result = NetErrorToPepperError(net_result);
938
939   if (state_.state() == TCPSocketState::CLOSED) {
940     // If this is called as a result of Close() being invoked and closing the
941     // pipe, fail the request without doing anything.
942     DCHECK_EQ(net_result, net::ERR_FAILED);
943     SendConnectError(context, pp_result);
944     return;
945   }
946
947   DCHECK(state_.IsPending(TCPSocketState::CONNECT));
948
949   do {
950     if (pp_result != PP_OK)
951       break;
952
953     PP_NetAddress_Private pp_local_addr =
954         NetAddressPrivateImpl::kInvalidNetAddress;
955     PP_NetAddress_Private pp_remote_addr =
956         NetAddressPrivateImpl::kInvalidNetAddress;
957     if (!local_addr || !peer_addr ||
958         !NetAddressPrivateImpl::IPEndPointToNetAddress(
959             local_addr->address().bytes(), local_addr->port(),
960             &pp_local_addr) ||
961         !NetAddressPrivateImpl::IPEndPointToNetAddress(
962             peer_addr->address().bytes(), peer_addr->port(), &pp_remote_addr)) {
963       pp_result = PP_ERROR_ADDRESS_INVALID;
964       break;
965     }
966
967     SetStreams(std::move(receive_stream), std::move(send_stream));
968
969     bound_socket_.reset();
970
971     SendConnectReply(context, PP_OK, pp_local_addr, pp_remote_addr);
972     state_.CompletePendingTransition(true);
973     return;
974   } while (false);
975
976   // Handle errors.
977
978   // This can happen even when the network service is behaving correctly, as
979   // we may see the |socket_observer_receiver_| closed before receiving an
980   // error.
981   pending_read_pp_error_ = PP_OK_COMPLETIONPENDING;
982   pending_write_pp_error_ = PP_OK_COMPLETIONPENDING;
983
984   Close();
985   SendConnectError(context, pp_result);
986
987   if (version_ != ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) {
988     // In order to maintain backward compatibility, allow further attempts
989     // to connect the socket.
990     state_ = TCPSocketState(TCPSocketState::INITIAL);
991   }
992 }
993
994 void PepperTCPSocketMessageFilter::OnSSLHandshakeCompleted(
995     const ppapi::host::ReplyMessageContext& context,
996     int net_result,
997     mojo::ScopedDataPipeConsumerHandle receive_stream,
998     mojo::ScopedDataPipeProducerHandle send_stream,
999     const absl::optional<net::SSLInfo>& ssl_info) {
1000   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1001
1002   int pp_result = NetErrorToPepperError(net_result);
1003   if (state_.state() == TCPSocketState::CLOSED) {
1004     // If this is called as a result of Close() being invoked and closing the
1005     // pipe, fail the request without doing anything.
1006     DCHECK_EQ(net_result, net::ERR_FAILED);
1007     SendSSLHandshakeReply(context, pp_result, absl::nullopt /* ssl_info */);
1008     return;
1009   }
1010
1011   DCHECK(state_.IsPending(TCPSocketState::SSL_CONNECT));
1012
1013   if (pp_result == PP_OK && !ssl_info)
1014     pp_result = PP_ERROR_FAILED;
1015
1016   state_.CompletePendingTransition(pp_result == PP_OK);
1017
1018   if (pp_result != PP_OK) {
1019     Close();
1020   } else {
1021     SetStreams(std::move(receive_stream), std::move(send_stream));
1022   }
1023
1024   SendSSLHandshakeReply(context, pp_result, ssl_info);
1025 }
1026
1027 void PepperTCPSocketMessageFilter::OnBindCompleted(
1028     const ppapi::host::ReplyMessageContext& context,
1029     int net_result,
1030     const absl::optional<net::IPEndPoint>& local_addr) {
1031   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1032
1033   int pp_result = NetErrorToPepperError(net_result);
1034   if (state_.state() == TCPSocketState::CLOSED) {
1035     // If this is called as a result of Close() being invoked and closing the
1036     // pipe, fail the request without doing anything.
1037     DCHECK_EQ(net_result, net::ERR_FAILED);
1038     SendBindError(context, pp_result);
1039     return;
1040   }
1041
1042   DCHECK(bound_socket_);
1043   DCHECK(state_.IsPending(TCPSocketState::BIND));
1044
1045   PP_NetAddress_Private bound_address =
1046       NetAddressPrivateImpl::kInvalidNetAddress;
1047   if (pp_result == PP_OK &&
1048       (!local_addr || !NetAddressPrivateImpl::IPEndPointToNetAddress(
1049                           local_addr->address().bytes(), local_addr->port(),
1050                           &bound_address))) {
1051     pp_result = PP_ERROR_ADDRESS_INVALID;
1052   }
1053
1054   if (pp_result != PP_OK) {
1055     bound_socket_.reset();
1056   } else {
1057     bind_output_ip_endpoint_ = *local_addr;
1058   }
1059
1060   SendBindReply(context, pp_result, bound_address);
1061   state_.CompletePendingTransition(pp_result == PP_OK);
1062 }
1063
1064 void PepperTCPSocketMessageFilter::OnListenCompleted(
1065     const ppapi::host::ReplyMessageContext& context,
1066     int net_result) {
1067   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1068
1069   int pp_result = NetErrorToPepperError(net_result);
1070   if (state_.state() == TCPSocketState::CLOSED) {
1071     // If this is called as a result of Close() being invoked and closing the
1072     // pipe, fail the request without doing anything.
1073     DCHECK_EQ(net_result, net::ERR_FAILED);
1074     SendListenReply(context, pp_result);
1075     return;
1076   }
1077
1078   DCHECK(state_.IsPending(TCPSocketState::LISTEN));
1079
1080 #if BUILDFLAG(IS_CHROMEOS_ASH)
1081   if (pp_result == PP_OK) {
1082     OpenFirewallHole(context);
1083     return;
1084   }
1085 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
1086
1087   SendListenReply(context, pp_result);
1088   state_.CompletePendingTransition(pp_result == PP_OK);
1089   if (pp_result != PP_OK)
1090     Close();
1091 }
1092
1093 void PepperTCPSocketMessageFilter::OnAcceptCompleted(
1094     const ppapi::host::ReplyMessageContext& context,
1095     mojo::PendingReceiver<network::mojom::SocketObserver>
1096         socket_observer_receiver,
1097     int net_result,
1098     const absl::optional<net::IPEndPoint>& remote_addr,
1099     mojo::PendingRemote<network::mojom::TCPConnectedSocket> connected_socket,
1100     mojo::ScopedDataPipeConsumerHandle receive_stream,
1101     mojo::ScopedDataPipeProducerHandle send_stream) {
1102   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1103   DCHECK(pending_accept_);
1104
1105   pending_accept_ = false;
1106   if (net_result != net::OK) {
1107     SendAcceptError(context, NetErrorToPepperError(net_result));
1108     return;
1109   }
1110
1111   if (!remote_addr || !connected_socket.is_valid()) {
1112     SendAcceptError(context, NetErrorToPepperError(net_result));
1113     return;
1114   }
1115
1116   DCHECK(socket_observer_receiver.is_valid());
1117
1118   PP_NetAddress_Private pp_remote_addr =
1119       NetAddressPrivateImpl::kInvalidNetAddress;
1120
1121   if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
1122           remote_addr->address().bytes(), remote_addr->port(),
1123           &pp_remote_addr)) {
1124     SendAcceptError(context, PP_ERROR_ADDRESS_INVALID);
1125     return;
1126   }
1127
1128   PP_NetAddress_Private bound_address =
1129       NetAddressPrivateImpl::kInvalidNetAddress;
1130   bool success = NetAddressPrivateImpl::IPEndPointToNetAddress(
1131       bind_output_ip_endpoint_.address().bytes(),
1132       bind_output_ip_endpoint_.port(), &bound_address);
1133   // This conversion should succeed, since it succeeded in OnBindComplete()
1134   // already.
1135   DCHECK(success);
1136
1137   GetUIThreadTaskRunner({})->PostTask(
1138       FROM_HERE,
1139       base::BindOnce(&PepperTCPSocketMessageFilter::OnAcceptCompletedOnIOThread,
1140                      this, context, std::move(connected_socket),
1141                      std::move(socket_observer_receiver),
1142                      std::move(receive_stream), std::move(send_stream),
1143                      bound_address, pp_remote_addr));
1144 }
1145
1146 void PepperTCPSocketMessageFilter::OnAcceptCompletedOnIOThread(
1147     const ppapi::host::ReplyMessageContext& context,
1148     mojo::PendingRemote<network::mojom::TCPConnectedSocket> connected_socket,
1149     mojo::PendingReceiver<network::mojom::SocketObserver>
1150         socket_observer_receiver,
1151     mojo::ScopedDataPipeConsumerHandle receive_stream,
1152     mojo::ScopedDataPipeProducerHandle send_stream,
1153     PP_NetAddress_Private pp_local_addr,
1154     PP_NetAddress_Private pp_remote_addr) {
1155   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1156
1157   if (!host_->IsValidInstance(instance_)) {
1158     // The instance has been removed while Accept was in progress. This object
1159     // should be destroyed and cleaned up after we release the reference we're
1160     // holding as a part of this function running so we just return without
1161     // doing anything.
1162     return;
1163   }
1164
1165   // |factory_| is guaranteed to be non-NULL here. Only those instances created
1166   // in CONNECTED state have a NULL |factory_|, while getting here requires
1167   // LISTENING state.
1168   DCHECK(factory_);
1169
1170   std::unique_ptr<ppapi::host::ResourceHost> host =
1171       factory_->CreateAcceptedTCPSocket(
1172           instance_, version_, std::move(connected_socket),
1173           std::move(socket_observer_receiver), std::move(receive_stream),
1174           std::move(send_stream));
1175   if (!host) {
1176     SendAcceptError(context, PP_ERROR_NOSPACE);
1177     return;
1178   }
1179
1180   int pending_host_id =
1181       host_->GetPpapiHost()->AddPendingResourceHost(std::move(host));
1182   if (pending_host_id) {
1183     SendAcceptReply(context, PP_OK, pending_host_id, pp_local_addr,
1184                     pp_remote_addr);
1185   } else {
1186     SendAcceptError(context, PP_ERROR_NOSPACE);
1187   }
1188 }
1189
1190 void PepperTCPSocketMessageFilter::SetStreams(
1191     mojo::ScopedDataPipeConsumerHandle receive_stream,
1192     mojo::ScopedDataPipeProducerHandle send_stream) {
1193   DCHECK(!read_watcher_);
1194   DCHECK(!write_watcher_);
1195
1196   receive_stream_ = std::move(receive_stream);
1197   read_watcher_ = std::make_unique<mojo::SimpleWatcher>(
1198       FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL);
1199   read_watcher_->Watch(
1200       receive_stream_.get(),
1201       MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
1202       MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
1203       base::BindRepeating(
1204           [](PepperTCPSocketMessageFilter* message_filter,
1205              MojoResult /* result */,
1206              const mojo::HandleSignalsState& /* state */) {
1207             // TryRead will correctly handle both cases (data ready to be
1208             // read, and the pipe was closed).
1209             message_filter->TryRead();
1210           },
1211           base::Unretained(this)));
1212
1213   send_stream_ = std::move(send_stream);
1214   write_watcher_ = std::make_unique<mojo::SimpleWatcher>(
1215       FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL);
1216   write_watcher_->Watch(
1217       send_stream_.get(),
1218       MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
1219       MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
1220       base::BindRepeating(
1221           [](PepperTCPSocketMessageFilter* message_filter,
1222              MojoResult /* result */,
1223              const mojo::HandleSignalsState& /* state */) {
1224             // TryRead will correctly handle both cases (data ready to be
1225             // read, and the pipe was closed).
1226             message_filter->TryWrite();
1227           },
1228           base::Unretained(this)));
1229 }
1230
1231 #if BUILDFLAG(IS_CHROMEOS_ASH)
1232 void PepperTCPSocketMessageFilter::OpenFirewallHole(
1233     const ppapi::host::ReplyMessageContext& context) {
1234   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1235   pepper_socket_utils::OpenTCPFirewallHole(
1236       bind_output_ip_endpoint_,
1237       base::BindOnce(&PepperTCPSocketMessageFilter::OnFirewallHoleOpened, this,
1238                      context));
1239 }
1240
1241 void PepperTCPSocketMessageFilter::OnFirewallHoleOpened(
1242     const ppapi::host::ReplyMessageContext& context,
1243     std::unique_ptr<ash::FirewallHole> hole) {
1244   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1245   DCHECK(state_.IsPending(TCPSocketState::LISTEN));
1246   LOG_IF(WARNING, !hole.get()) << "Firewall hole could not be opened.";
1247   firewall_hole_.reset(hole.release());
1248
1249   SendListenReply(context, PP_OK);
1250   state_.CompletePendingTransition(true);
1251 }
1252 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
1253
1254 void PepperTCPSocketMessageFilter::SendBindReply(
1255     const ppapi::host::ReplyMessageContext& context,
1256     int32_t pp_result,
1257     const PP_NetAddress_Private& local_addr) {
1258   ppapi::host::ReplyMessageContext reply_context(context);
1259   reply_context.params.set_result(pp_result);
1260   SendReply(reply_context, PpapiPluginMsg_TCPSocket_BindReply(local_addr));
1261 }
1262
1263 void PepperTCPSocketMessageFilter::SendBindError(
1264     const ppapi::host::ReplyMessageContext& context,
1265     int32_t pp_error) {
1266   SendBindReply(context, pp_error, NetAddressPrivateImpl::kInvalidNetAddress);
1267 }
1268
1269 void PepperTCPSocketMessageFilter::SendConnectReply(
1270     const ppapi::host::ReplyMessageContext& context,
1271     int32_t pp_result,
1272     const PP_NetAddress_Private& local_addr,
1273     const PP_NetAddress_Private& remote_addr) {
1274   UMA_HISTOGRAM_BOOLEAN("Pepper.PluginContextSecurity.TCPConnect",
1275                         is_potentially_secure_plugin_context_);
1276
1277   ppapi::host::ReplyMessageContext reply_context(context);
1278   reply_context.params.set_result(pp_result);
1279   SendReply(reply_context,
1280             PpapiPluginMsg_TCPSocket_ConnectReply(local_addr, remote_addr));
1281 }
1282
1283 void PepperTCPSocketMessageFilter::SendConnectError(
1284     const ppapi::host::ReplyMessageContext& context,
1285     int32_t pp_error) {
1286   SendConnectReply(context, pp_error, NetAddressPrivateImpl::kInvalidNetAddress,
1287                    NetAddressPrivateImpl::kInvalidNetAddress);
1288 }
1289
1290 void PepperTCPSocketMessageFilter::SendSSLHandshakeReply(
1291     const ppapi::host::ReplyMessageContext& context,
1292     int32_t pp_result,
1293     const absl::optional<net::SSLInfo>& ssl_info) {
1294   ppapi::host::ReplyMessageContext reply_context(context);
1295   reply_context.params.set_result(pp_result);
1296   ppapi::PPB_X509Certificate_Fields certificate_fields;
1297   if (pp_result == PP_OK) {
1298     DCHECK(ssl_info);
1299     if (ssl_info->cert.get()) {
1300       ppapi::PPB_X509Util_Shared::GetCertificateFields(*ssl_info->cert,
1301                                                        &certificate_fields);
1302     }
1303   }
1304   SendReply(reply_context,
1305             PpapiPluginMsg_TCPSocket_SSLHandshakeReply(certificate_fields));
1306 }
1307
1308 void PepperTCPSocketMessageFilter::SendReadReply(int32_t pp_result,
1309                                                  const ppapi::DataView& data) {
1310   DCHECK(pending_read_context_.is_valid());
1311   DCHECK_GT(pending_read_size_, 0u);
1312
1313   pending_read_context_.params.set_result(pp_result);
1314   SendReply(pending_read_context_, PpapiPluginMsg_TCPSocket_ReadReply(data));
1315
1316   pending_read_context_ = ppapi::host::ReplyMessageContext();
1317   pending_read_size_ = 0;
1318 }
1319
1320 void PepperTCPSocketMessageFilter::SendReadError(int32_t pp_error) {
1321   SendReadReply(pp_error, ppapi::DataView());
1322 }
1323
1324 void PepperTCPSocketMessageFilter::SendWriteReply(int32_t pp_result) {
1325   DCHECK(pending_write_context_.is_valid());
1326   DCHECK_NE(pending_write_data_.size, 0u);
1327   DCHECK(pp_result <= 0 ||
1328          static_cast<uint32_t>(pp_result) == pending_write_data_.size);
1329   DCHECK(pp_result <= 0 ||
1330          static_cast<uint32_t>(pp_result) == pending_write_bytes_written_);
1331
1332   pending_write_context_.params.set_result(pp_result);
1333   SendReply(pending_write_context_, PpapiPluginMsg_TCPSocket_WriteReply());
1334
1335   pending_write_context_ = ppapi::host::ReplyMessageContext();
1336   pending_write_data_.size = 0;
1337   pending_write_data_.data = NULL;
1338   pending_write_bytes_written_ = 0;
1339 }
1340
1341 void PepperTCPSocketMessageFilter::SendListenReply(
1342     const ppapi::host::ReplyMessageContext& context,
1343     int32_t pp_result) {
1344   ppapi::host::ReplyMessageContext reply_context(context);
1345   reply_context.params.set_result(pp_result);
1346   SendReply(reply_context, PpapiPluginMsg_TCPSocket_ListenReply());
1347 }
1348
1349 void PepperTCPSocketMessageFilter::SendAcceptReply(
1350     const ppapi::host::ReplyMessageContext& context,
1351     int32_t pp_result,
1352     int pending_host_id,
1353     const PP_NetAddress_Private& local_addr,
1354     const PP_NetAddress_Private& remote_addr) {
1355   ppapi::host::ReplyMessageContext reply_context(context);
1356   reply_context.params.set_result(pp_result);
1357   SendReply(reply_context, PpapiPluginMsg_TCPSocket_AcceptReply(
1358                                pending_host_id, local_addr, remote_addr));
1359 }
1360
1361 void PepperTCPSocketMessageFilter::SendAcceptError(
1362     const ppapi::host::ReplyMessageContext& context,
1363     int32_t pp_error) {
1364   SendAcceptReply(context, pp_error, 0,
1365                   NetAddressPrivateImpl::kInvalidNetAddress,
1366                   NetAddressPrivateImpl::kInvalidNetAddress);
1367 }
1368
1369 void PepperTCPSocketMessageFilter::Close() {
1370   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1371
1372   // Need to do these first, as destroying Mojo pipes may invoke some of the
1373   // callbacks with failure messages.
1374   weak_ptr_factory_.InvalidateWeakPtrs();
1375   state_.DoTransition(TCPSocketState::CLOSE, true);
1376
1377 #if BUILDFLAG(IS_CHROMEOS_ASH)
1378   // Close the firewall hole, it is no longer needed.
1379   firewall_hole_.reset();
1380 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
1381
1382   // Make sure there are no further callbacks from Mojo, which could end up in a
1383   // double free (Add ref on the UI thread, while a deletion is pending on the
1384   // IO thread), and that they're closed on the correct thread.
1385   bound_socket_.reset();
1386   connected_socket_.reset();
1387   tls_client_socket_.reset();
1388   server_socket_.reset();
1389   receiver_.reset();
1390   socket_observer_receiver_.reset();
1391
1392   read_watcher_.reset();
1393   receive_stream_.reset();
1394   write_watcher_.reset();
1395   send_stream_.reset();
1396 }
1397
1398 network::mojom::NetworkContext*
1399 PepperTCPSocketMessageFilter::GetNetworkContext() const {
1400   if (network_context_for_testing)
1401     return network_context_for_testing;
1402
1403   RenderProcessHost* render_process_host =
1404       RenderProcessHost::FromID(render_process_id_);
1405   if (!render_process_host)
1406     return nullptr;
1407
1408   return render_process_host->GetStoragePartition()->GetNetworkContext();
1409 }
1410
1411 template <class ReturnMessage>
1412 base::OnceCallback<void(int result)>
1413 PepperTCPSocketMessageFilter::CreateCompletionCallback(
1414     const ppapi::host::HostMessageContext* context) {
1415   return mojo::WrapCallbackWithDefaultInvokeIfNotRun(
1416       base::BindOnce(&PepperTCPSocketMessageFilter::ReturnResult<ReturnMessage>,
1417                      base::Unretained(this),
1418                      context->MakeReplyMessageContext()),
1419       net::ERR_FAILED);
1420 }
1421
1422 template <class ReturnMessage>
1423 void PepperTCPSocketMessageFilter::ReturnResult(
1424     ppapi::host::ReplyMessageContext context,
1425     int net_result) {
1426   context.params.set_result(NetErrorToPepperError(net_result));
1427   SendReply(context, ReturnMessage());
1428 }
1429
1430 }  // namespace content