blob: 3615f2cbf695b658a63ef09cbb9f936db74dc2d6 [file] [log] [blame]
[email protected]518c63a2014-07-24 03:51:231// 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 "net/socket/unix_domain_client_socket_posix.h"
6
7#include <sys/socket.h>
8#include <sys/un.h>
dchengc7eeda422015-12-26 03:56:489#include <utility>
[email protected]518c63a2014-07-24 03:51:2310
11#include "base/logging.h"
[email protected]518c63a2014-07-24 03:51:2312#include "net/base/net_errors.h"
tfarina3d87d7cd2016-01-13 02:26:5913#include "net/base/sockaddr_storage.h"
tfarina4eb7aad82015-09-14 17:10:3414#include "net/socket/socket_posix.h"
[email protected]518c63a2014-07-24 03:51:2315
16namespace net {
17
18UnixDomainClientSocket::UnixDomainClientSocket(const std::string& socket_path,
19 bool use_abstract_namespace)
20 : socket_path_(socket_path),
21 use_abstract_namespace_(use_abstract_namespace) {
22}
23
danakj655b66c2016-04-16 00:51:3824UnixDomainClientSocket::UnixDomainClientSocket(
25 std::unique_ptr<SocketPosix> socket)
dchengc7eeda422015-12-26 03:56:4826 : use_abstract_namespace_(false), socket_(std::move(socket)) {}
[email protected]518c63a2014-07-24 03:51:2327
28UnixDomainClientSocket::~UnixDomainClientSocket() {
29 Disconnect();
30}
31
32// static
33bool UnixDomainClientSocket::FillAddress(const std::string& socket_path,
34 bool use_abstract_namespace,
35 SockaddrStorage* address) {
tfarina3c80dac2016-03-02 18:20:0536 // Caller should provide a non-empty path for the socket address.
37 if (socket_path.empty())
38 return false;
39
[email protected]518c63a2014-07-24 03:51:2340 size_t path_max = address->addr_len - offsetof(struct sockaddr_un, sun_path);
41 // Non abstract namespace pathname should be null-terminated. Abstract
42 // namespace pathname must start with '\0'. So, the size is always greater
43 // than socket_path size by 1.
44 size_t path_size = socket_path.size() + 1;
45 if (path_size > path_max)
46 return false;
47
tfarina3c80dac2016-03-02 18:20:0548 struct sockaddr_un* socket_addr =
49 reinterpret_cast<struct sockaddr_un*>(address->addr);
[email protected]518c63a2014-07-24 03:51:2350 memset(socket_addr, 0, address->addr_len);
51 socket_addr->sun_family = AF_UNIX;
52 address->addr_len = path_size + offsetof(struct sockaddr_un, sun_path);
53 if (!use_abstract_namespace) {
54 memcpy(socket_addr->sun_path, socket_path.c_str(), socket_path.size());
55 return true;
56 }
57
58#if defined(OS_ANDROID) || defined(OS_LINUX)
59 // Convert the path given into abstract socket name. It must start with
60 // the '\0' character, so we are adding it. |addr_len| must specify the
61 // length of the structure exactly, as potentially the socket name may
62 // have '\0' characters embedded (although we don't support this).
63 // Note that addr.sun_path is already zero initialized.
64 memcpy(socket_addr->sun_path + 1, socket_path.c_str(), socket_path.size());
65 return true;
66#else
67 return false;
68#endif
69}
70
71int UnixDomainClientSocket::Connect(const CompletionCallback& callback) {
72 DCHECK(!socket_);
73
[email protected]518c63a2014-07-24 03:51:2374 SockaddrStorage address;
75 if (!FillAddress(socket_path_, use_abstract_namespace_, &address))
76 return ERR_ADDRESS_INVALID;
77
tfarina4eb7aad82015-09-14 17:10:3478 socket_.reset(new SocketPosix);
[email protected]518c63a2014-07-24 03:51:2379 int rv = socket_->Open(AF_UNIX);
80 DCHECK_NE(ERR_IO_PENDING, rv);
81 if (rv != OK)
82 return rv;
83
84 return socket_->Connect(address, callback);
85}
86
87void UnixDomainClientSocket::Disconnect() {
88 socket_.reset();
89}
90
91bool UnixDomainClientSocket::IsConnected() const {
92 return socket_ && socket_->IsConnected();
93}
94
95bool UnixDomainClientSocket::IsConnectedAndIdle() const {
96 return socket_ && socket_->IsConnectedAndIdle();
97}
98
99int UnixDomainClientSocket::GetPeerAddress(IPEndPoint* address) const {
tobiasjsff494022015-01-08 19:40:52100 // Unix domain sockets have no valid associated addr/port;
101 // return either not connected or address invalid.
102 DCHECK(address);
103
104 if (!IsConnected())
105 return ERR_SOCKET_NOT_CONNECTED;
106
107 return ERR_ADDRESS_INVALID;
[email protected]518c63a2014-07-24 03:51:23108}
109
110int UnixDomainClientSocket::GetLocalAddress(IPEndPoint* address) const {
tobiasjsff494022015-01-08 19:40:52111 // Unix domain sockets have no valid associated addr/port;
112 // return either not connected or address invalid.
113 DCHECK(address);
114
115 if (!socket_)
116 return ERR_SOCKET_NOT_CONNECTED;
117
118 return ERR_ADDRESS_INVALID;
[email protected]518c63a2014-07-24 03:51:23119}
120
tfarina428341112016-09-22 13:38:20121const NetLogWithSource& UnixDomainClientSocket::NetLog() const {
[email protected]518c63a2014-07-24 03:51:23122 return net_log_;
123}
124
125void UnixDomainClientSocket::SetSubresourceSpeculation() {
126}
127
128void UnixDomainClientSocket::SetOmniboxSpeculation() {
129}
130
131bool UnixDomainClientSocket::WasEverUsed() const {
132 return true; // We don't care.
133}
134
[email protected]518c63a2014-07-24 03:51:23135bool UnixDomainClientSocket::WasNpnNegotiated() const {
136 return false;
137}
138
139NextProto UnixDomainClientSocket::GetNegotiatedProtocol() const {
140 return kProtoUnknown;
141}
142
143bool UnixDomainClientSocket::GetSSLInfo(SSLInfo* ssl_info) {
144 return false;
145}
146
ttuttle23fdb7b2015-05-15 01:28:03147void UnixDomainClientSocket::GetConnectionAttempts(
148 ConnectionAttempts* out) const {
149 out->clear();
150}
151
tbansalf82cc8e2015-10-14 20:05:49152int64_t UnixDomainClientSocket::GetTotalReceivedBytes() const {
153 NOTIMPLEMENTED();
154 return 0;
155}
156
[email protected]518c63a2014-07-24 03:51:23157int UnixDomainClientSocket::Read(IOBuffer* buf, int buf_len,
158 const CompletionCallback& callback) {
159 DCHECK(socket_);
160 return socket_->Read(buf, buf_len, callback);
161}
162
163int UnixDomainClientSocket::Write(IOBuffer* buf, int buf_len,
164 const CompletionCallback& callback) {
165 DCHECK(socket_);
166 return socket_->Write(buf, buf_len, callback);
167}
168
Avi Drissman13fc8932015-12-20 04:40:46169int UnixDomainClientSocket::SetReceiveBufferSize(int32_t size) {
[email protected]518c63a2014-07-24 03:51:23170 NOTIMPLEMENTED();
171 return ERR_NOT_IMPLEMENTED;
172}
173
Avi Drissman13fc8932015-12-20 04:40:46174int UnixDomainClientSocket::SetSendBufferSize(int32_t size) {
[email protected]518c63a2014-07-24 03:51:23175 NOTIMPLEMENTED();
176 return ERR_NOT_IMPLEMENTED;
177}
178
cmasoneca100d52014-09-03 18:11:11179SocketDescriptor UnixDomainClientSocket::ReleaseConnectedSocket() {
180 DCHECK(socket_);
181 DCHECK(socket_->IsConnected());
182
183 SocketDescriptor socket_fd = socket_->ReleaseConnectedSocket();
184 socket_.reset();
185 return socket_fd;
186}
187
[email protected]518c63a2014-07-24 03:51:23188} // namespace net