Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 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 "mojo/shell/incoming_connection_listener.h" | |
| 6 | |
| 7 #include "base/callback.h" | |
| 8 #include "base/files/file_path.h" | |
| 9 #include "base/files/file_util.h" | |
| 10 #include "base/logging.h" | |
| 11 #include "base/memory/scoped_ptr.h" | |
| 12 #include "base/sequenced_task_runner.h" | |
| 13 #include "base/tracked_objects.h" | |
| 14 #include "net/base/net_errors.h" | |
| 15 #include "net/socket/socket_descriptor.h" | |
| 16 #include "net/socket/unix_domain_server_socket_posix.h" | |
| 17 | |
| 18 namespace mojo { | |
| 19 namespace shell { | |
| 20 | |
| 21 namespace { | |
| 22 // TODO(cmasone): Figure out what we should be doing about "authenticating" the | |
| 23 // process trying to connect. | |
| 24 bool Yes(const net::UnixDomainServerSocket::Credentials& ignored) { | |
| 25 return true; | |
| 26 } | |
| 27 } // anonymous namespace | |
| 28 | |
| 29 IncomingConnectionListener::Delegate::Delegate() { | |
| 30 } | |
| 31 | |
| 32 IncomingConnectionListener::Delegate::~Delegate() { | |
| 33 } | |
| 34 | |
| 35 IncomingConnectionListener::IncomingConnectionListener( | |
| 36 const base::FilePath& socket_path, | |
| 37 Delegate* delegate) | |
| 38 : delegate_(delegate), | |
| 39 socket_path_(socket_path), | |
| 40 listen_socket_(base::Bind(&Yes), false), | |
| 41 incoming_socket_(net::kInvalidSocket), | |
| 42 weak_ptr_factory_(this) { | |
| 43 DCHECK(delegate_); | |
| 44 } | |
| 45 | |
| 46 IncomingConnectionListener::~IncomingConnectionListener() { | |
| 47 weak_ptr_factory_.InvalidateWeakPtrs(); | |
| 48 if (!base::DeleteFile(socket_path_, false)) | |
| 49 PLOG(ERROR) << "Listening Unix domain socket can't be destroyed."; | |
| 50 } | |
| 51 | |
| 52 void IncomingConnectionListener::StartListening() { | |
| 53 DCHECK(listen_thread_checker_.CalledOnValidThread()); | |
| 54 | |
| 55 int rv = net::OK; | |
| 56 if (base::PathExists(socket_path_)) { | |
| 57 LOG(ERROR) << "Listening socket file already exists."; | |
| 58 rv = net::ERR_FILE_EXISTS; | |
| 59 } else if (!base::DirectoryExists(socket_path_.DirName())) { | |
| 60 LOG(ERROR) << "Directorty for listening socket does not exist."; | |
| 61 rv = net::ERR_FILE_NOT_FOUND; | |
| 62 } else if (!base::PathIsWritable(socket_path_.DirName())) { | |
| 63 LOG(ERROR) << "Listening socket file path is not writable."; | |
| 64 rv = net::ERR_ACCESS_DENIED; | |
| 65 } else { | |
| 66 const std::string& socket_address = socket_path_.value(); | |
| 67 rv = listen_socket_.ListenWithAddressAndPort(socket_address, 0, 100); | |
| 68 } | |
| 69 | |
| 70 // Call OnListening() before Accept(), so that the delegate is certain to | |
| 71 // hear about listening before a connection might be accepted below. | |
| 72 delegate_->OnListening(rv); | |
| 73 if (rv == net::OK) { | |
|
DaveMoore
2014/09/26 22:48:57
Nit: no braces
Chris Masone
2014/09/27 00:46:30
Done.
| |
| 74 Accept(); | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 void IncomingConnectionListener::Accept() { | |
| 79 DCHECK(listen_thread_checker_.CalledOnValidThread()); | |
| 80 int rv = listen_socket_.AcceptSocketDescriptor( | |
| 81 &incoming_socket_, | |
| 82 base::Bind(&IncomingConnectionListener::OnAccept, | |
| 83 weak_ptr_factory_.GetWeakPtr())); | |
| 84 | |
| 85 // If rv == net::ERR_IO_PENDING), listen_socket_ will call | |
| 86 // OnAccept() later, when a connection attempt comes in. | |
| 87 if (rv != net::ERR_IO_PENDING) { | |
| 88 DVLOG_IF(1, rv == net::OK) << "Accept succeeded immediately"; | |
| 89 OnAccept(rv); | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 void IncomingConnectionListener::OnAccept(int rv) { | |
| 94 DCHECK(listen_thread_checker_.CalledOnValidThread()); | |
| 95 | |
| 96 if (rv != net::OK || incoming_socket_ == net::kInvalidSocket) { | |
| 97 LOG_IF(ERROR, rv != net::OK) << "Accept failed " << net::ErrorToString(rv); | |
| 98 PLOG_IF(ERROR, rv == net::OK) << "Socket invalid"; | |
| 99 } else { | |
| 100 // Passes ownership of incoming_socket_ to delegate_. | |
| 101 delegate_->OnConnection(incoming_socket_); | |
| 102 incoming_socket_ = net::kInvalidSocket; | |
| 103 } | |
| 104 | |
| 105 // Continue waiting to accept incoming connections... | |
| 106 Accept(); | |
| 107 } | |
| 108 | |
| 109 } // namespace shell | |
| 110 } // namespace mojo | |
| OLD | NEW |