blob: ffc858cc471e4101c5796eeb3b022e9ad93e3249 [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]a2b2cfc2017-12-06 09:06:0815#include "net/traffic_annotation/network_traffic_annotation.h"
[email protected]518c63a2014-07-24 03:51:2316
17namespace net {
18
19UnixDomainClientSocket::UnixDomainClientSocket(const std::string& socket_path,
20 bool use_abstract_namespace)
21 : socket_path_(socket_path),
22 use_abstract_namespace_(use_abstract_namespace) {
23}
24
danakj655b66c2016-04-16 00:51:3825UnixDomainClientSocket::UnixDomainClientSocket(
26 std::unique_ptr<SocketPosix> socket)
dchengc7eeda422015-12-26 03:56:4827 : use_abstract_namespace_(false), socket_(std::move(socket)) {}
[email protected]518c63a2014-07-24 03:51:2328
29UnixDomainClientSocket::~UnixDomainClientSocket() {
30 Disconnect();
31}
32
33// static
34bool UnixDomainClientSocket::FillAddress(const std::string& socket_path,
35 bool use_abstract_namespace,
36 SockaddrStorage* address) {
tfarina3c80dac2016-03-02 18:20:0537 // Caller should provide a non-empty path for the socket address.
38 if (socket_path.empty())
39 return false;
40
[email protected]518c63a2014-07-24 03:51:2341 size_t path_max = address->addr_len - offsetof(struct sockaddr_un, sun_path);
42 // Non abstract namespace pathname should be null-terminated. Abstract
43 // namespace pathname must start with '\0'. So, the size is always greater
44 // than socket_path size by 1.
45 size_t path_size = socket_path.size() + 1;
46 if (path_size > path_max)
47 return false;
48
tfarina3c80dac2016-03-02 18:20:0549 struct sockaddr_un* socket_addr =
50 reinterpret_cast<struct sockaddr_un*>(address->addr);
[email protected]518c63a2014-07-24 03:51:2351 memset(socket_addr, 0, address->addr_len);
52 socket_addr->sun_family = AF_UNIX;
53 address->addr_len = path_size + offsetof(struct sockaddr_un, sun_path);
54 if (!use_abstract_namespace) {
55 memcpy(socket_addr->sun_path, socket_path.c_str(), socket_path.size());
56 return true;
57 }
58
59#if defined(OS_ANDROID) || defined(OS_LINUX)
60 // Convert the path given into abstract socket name. It must start with
61 // the '\0' character, so we are adding it. |addr_len| must specify the
62 // length of the structure exactly, as potentially the socket name may
63 // have '\0' characters embedded (although we don't support this).
64 // Note that addr.sun_path is already zero initialized.
65 memcpy(socket_addr->sun_path + 1, socket_path.c_str(), socket_path.size());
66 return true;
67#else
68 return false;
69#endif
70}
71
Brad Lassey3a814172018-04-26 03:30:2172int UnixDomainClientSocket::Connect(CompletionOnceCallback callback) {
[email protected]518c63a2014-07-24 03:51:2373 DCHECK(!socket_);
74
[email protected]518c63a2014-07-24 03:51:2375 SockaddrStorage address;
76 if (!FillAddress(socket_path_, use_abstract_namespace_, &address))
77 return ERR_ADDRESS_INVALID;
78
tfarina4eb7aad82015-09-14 17:10:3479 socket_.reset(new SocketPosix);
[email protected]518c63a2014-07-24 03:51:2380 int rv = socket_->Open(AF_UNIX);
81 DCHECK_NE(ERR_IO_PENDING, rv);
82 if (rv != OK)
83 return rv;
84
Brad Lassey3a814172018-04-26 03:30:2185 return socket_->Connect(address, std::move(callback));
[email protected]518c63a2014-07-24 03:51:2386}
87
88void UnixDomainClientSocket::Disconnect() {
89 socket_.reset();
90}
91
92bool UnixDomainClientSocket::IsConnected() const {
93 return socket_ && socket_->IsConnected();
94}
95
96bool UnixDomainClientSocket::IsConnectedAndIdle() const {
97 return socket_ && socket_->IsConnectedAndIdle();
98}
99
100int UnixDomainClientSocket::GetPeerAddress(IPEndPoint* address) const {
tobiasjsff494022015-01-08 19:40:52101 // Unix domain sockets have no valid associated addr/port;
102 // return either not connected or address invalid.
103 DCHECK(address);
104
105 if (!IsConnected())
106 return ERR_SOCKET_NOT_CONNECTED;
107
108 return ERR_ADDRESS_INVALID;
[email protected]518c63a2014-07-24 03:51:23109}
110
111int UnixDomainClientSocket::GetLocalAddress(IPEndPoint* address) const {
tobiasjsff494022015-01-08 19:40:52112 // Unix domain sockets have no valid associated addr/port;
113 // return either not connected or address invalid.
114 DCHECK(address);
115
116 if (!socket_)
117 return ERR_SOCKET_NOT_CONNECTED;
118
119 return ERR_ADDRESS_INVALID;
[email protected]518c63a2014-07-24 03:51:23120}
121
tfarina42834112016-09-22 13:38:20122const NetLogWithSource& UnixDomainClientSocket::NetLog() const {
[email protected]518c63a2014-07-24 03:51:23123 return net_log_;
124}
125
126void UnixDomainClientSocket::SetSubresourceSpeculation() {
127}
128
129void UnixDomainClientSocket::SetOmniboxSpeculation() {
130}
131
132bool UnixDomainClientSocket::WasEverUsed() const {
133 return true; // We don't care.
134}
135
tfarina2846404c2016-12-25 14:31:37136bool UnixDomainClientSocket::WasAlpnNegotiated() const {
[email protected]518c63a2014-07-24 03:51:23137 return false;
138}
139
140NextProto UnixDomainClientSocket::GetNegotiatedProtocol() const {
141 return kProtoUnknown;
142}
143
144bool UnixDomainClientSocket::GetSSLInfo(SSLInfo* ssl_info) {
145 return false;
146}
147
ttuttle23fdb7b2015-05-15 01:28:03148void UnixDomainClientSocket::GetConnectionAttempts(
149 ConnectionAttempts* out) const {
150 out->clear();
151}
152
tbansalf82cc8e2015-10-14 20:05:49153int64_t UnixDomainClientSocket::GetTotalReceivedBytes() const {
154 NOTIMPLEMENTED();
155 return 0;
156}
157
Paul Jensen0f49dec2017-12-12 23:39:58158void UnixDomainClientSocket::ApplySocketTag(const SocketTag& tag) {
159 // Ignore socket tags as Unix domain sockets are local only.
160}
161
Brad Lassey3a814172018-04-26 03:30:21162int UnixDomainClientSocket::Read(IOBuffer* buf,
163 int buf_len,
164 CompletionOnceCallback callback) {
[email protected]518c63a2014-07-24 03:51:23165 DCHECK(socket_);
Brad Lassey3a814172018-04-26 03:30:21166 return socket_->Read(buf, buf_len, std::move(callback));
[email protected]518c63a2014-07-24 03:51:23167}
168
[email protected]a2b2cfc2017-12-06 09:06:08169int UnixDomainClientSocket::Write(
170 IOBuffer* buf,
171 int buf_len,
Brad Lassey3a814172018-04-26 03:30:21172 CompletionOnceCallback callback,
[email protected]a2b2cfc2017-12-06 09:06:08173 const NetworkTrafficAnnotationTag& traffic_annotation) {
[email protected]518c63a2014-07-24 03:51:23174 DCHECK(socket_);
Brad Lassey3a814172018-04-26 03:30:21175 return socket_->Write(buf, buf_len, std::move(callback), traffic_annotation);
[email protected]518c63a2014-07-24 03:51:23176}
177
Avi Drissman13fc8932015-12-20 04:40:46178int UnixDomainClientSocket::SetReceiveBufferSize(int32_t size) {
[email protected]518c63a2014-07-24 03:51:23179 NOTIMPLEMENTED();
180 return ERR_NOT_IMPLEMENTED;
181}
182
Avi Drissman13fc8932015-12-20 04:40:46183int UnixDomainClientSocket::SetSendBufferSize(int32_t size) {
[email protected]518c63a2014-07-24 03:51:23184 NOTIMPLEMENTED();
185 return ERR_NOT_IMPLEMENTED;
186}
187
cmasoneca100d52014-09-03 18:11:11188SocketDescriptor UnixDomainClientSocket::ReleaseConnectedSocket() {
189 DCHECK(socket_);
190 DCHECK(socket_->IsConnected());
191
192 SocketDescriptor socket_fd = socket_->ReleaseConnectedSocket();
193 socket_.reset();
194 return socket_fd;
195}
196
[email protected]518c63a2014-07-24 03:51:23197} // namespace net