| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/socket/unix_domain_client_socket_posix.h" |
| |
| #include <sys/socket.h> |
| #include <sys/un.h> |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/check_op.h" |
| #include "base/notreached.h" |
| #include "build/build_config.h" |
| #include "net/base/net_errors.h" |
| #include "net/base/sockaddr_storage.h" |
| #include "net/base/sockaddr_util_posix.h" |
| #include "net/socket/socket_posix.h" |
| #include "net/traffic_annotation/network_traffic_annotation.h" |
| |
| namespace net { |
| |
| UnixDomainClientSocket::UnixDomainClientSocket(const std::string& socket_path, |
| bool use_abstract_namespace) |
| : socket_path_(socket_path), |
| use_abstract_namespace_(use_abstract_namespace) { |
| } |
| |
| UnixDomainClientSocket::UnixDomainClientSocket( |
| std::unique_ptr<SocketPosix> socket) |
| : use_abstract_namespace_(false), socket_(std::move(socket)) {} |
| |
| UnixDomainClientSocket::~UnixDomainClientSocket() { |
| Disconnect(); |
| } |
| |
| int UnixDomainClientSocket::Connect(CompletionOnceCallback callback) { |
| if (IsConnected()) |
| return OK; |
| |
| SockaddrStorage address; |
| if (!FillUnixAddress(socket_path_, use_abstract_namespace_, &address)) |
| return ERR_ADDRESS_INVALID; |
| |
| socket_ = std::make_unique<SocketPosix>(); |
| int rv = socket_->Open(AF_UNIX); |
| DCHECK_NE(ERR_IO_PENDING, rv); |
| if (rv != OK) |
| return rv; |
| |
| return socket_->Connect(address, std::move(callback)); |
| } |
| |
| void UnixDomainClientSocket::Disconnect() { |
| socket_.reset(); |
| } |
| |
| bool UnixDomainClientSocket::IsConnected() const { |
| return socket_ && socket_->IsConnected(); |
| } |
| |
| bool UnixDomainClientSocket::IsConnectedAndIdle() const { |
| return socket_ && socket_->IsConnectedAndIdle(); |
| } |
| |
| int UnixDomainClientSocket::GetPeerAddress(IPEndPoint* address) const { |
| // Unix domain sockets have no valid associated addr/port; |
| // return either not connected or address invalid. |
| DCHECK(address); |
| |
| if (!IsConnected()) |
| return ERR_SOCKET_NOT_CONNECTED; |
| |
| return ERR_ADDRESS_INVALID; |
| } |
| |
| int UnixDomainClientSocket::GetLocalAddress(IPEndPoint* address) const { |
| // Unix domain sockets have no valid associated addr/port; |
| // return either not connected or address invalid. |
| DCHECK(address); |
| |
| if (!socket_) |
| return ERR_SOCKET_NOT_CONNECTED; |
| |
| return ERR_ADDRESS_INVALID; |
| } |
| |
| const NetLogWithSource& UnixDomainClientSocket::NetLog() const { |
| return net_log_; |
| } |
| |
| bool UnixDomainClientSocket::WasEverUsed() const { |
| return true; // We don't care. |
| } |
| |
| bool UnixDomainClientSocket::WasAlpnNegotiated() const { |
| return false; |
| } |
| |
| NextProto UnixDomainClientSocket::GetNegotiatedProtocol() const { |
| return kProtoUnknown; |
| } |
| |
| bool UnixDomainClientSocket::GetSSLInfo(SSLInfo* ssl_info) { |
| return false; |
| } |
| |
| int64_t UnixDomainClientSocket::GetTotalReceivedBytes() const { |
| NOTIMPLEMENTED(); |
| return 0; |
| } |
| |
| void UnixDomainClientSocket::ApplySocketTag(const SocketTag& tag) { |
| // Ignore socket tags as Unix domain sockets are local only. |
| } |
| |
| int UnixDomainClientSocket::Read(IOBuffer* buf, |
| int buf_len, |
| CompletionOnceCallback callback) { |
| DCHECK(socket_); |
| return socket_->Read(buf, buf_len, std::move(callback)); |
| } |
| |
| int UnixDomainClientSocket::Write( |
| IOBuffer* buf, |
| int buf_len, |
| CompletionOnceCallback callback, |
| const NetworkTrafficAnnotationTag& traffic_annotation) { |
| DCHECK(socket_); |
| return socket_->Write(buf, buf_len, std::move(callback), traffic_annotation); |
| } |
| |
| int UnixDomainClientSocket::SetReceiveBufferSize(int32_t size) { |
| NOTIMPLEMENTED(); |
| return ERR_NOT_IMPLEMENTED; |
| } |
| |
| int UnixDomainClientSocket::SetSendBufferSize(int32_t size) { |
| NOTIMPLEMENTED(); |
| return ERR_NOT_IMPLEMENTED; |
| } |
| |
| SocketDescriptor UnixDomainClientSocket::ReleaseConnectedSocket() { |
| DCHECK(socket_); |
| DCHECK(socket_->IsConnected()); |
| |
| SocketDescriptor socket_fd = socket_->ReleaseConnectedSocket(); |
| socket_.reset(); |
| return socket_fd; |
| } |
| |
| } // namespace net |