1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/socket/tcp_server_socket.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <memory>
8*6777b538SAndroid Build Coastguard Worker #include <utility>
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
15*6777b538SAndroid Build Coastguard Worker #include "net/socket/socket_descriptor.h"
16*6777b538SAndroid Build Coastguard Worker #include "net/socket/tcp_client_socket.h"
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker namespace net {
19*6777b538SAndroid Build Coastguard Worker
TCPServerSocket(NetLog * net_log,const NetLogSource & source)20*6777b538SAndroid Build Coastguard Worker TCPServerSocket::TCPServerSocket(NetLog* net_log, const NetLogSource& source)
21*6777b538SAndroid Build Coastguard Worker : TCPServerSocket(
22*6777b538SAndroid Build Coastguard Worker std::make_unique<TCPSocket>(nullptr /* socket_performance_watcher */,
23*6777b538SAndroid Build Coastguard Worker net_log,
24*6777b538SAndroid Build Coastguard Worker source)) {}
25*6777b538SAndroid Build Coastguard Worker
TCPServerSocket(std::unique_ptr<TCPSocket> socket)26*6777b538SAndroid Build Coastguard Worker TCPServerSocket::TCPServerSocket(std::unique_ptr<TCPSocket> socket)
27*6777b538SAndroid Build Coastguard Worker : socket_(std::move(socket)) {}
28*6777b538SAndroid Build Coastguard Worker
AdoptSocket(SocketDescriptor socket)29*6777b538SAndroid Build Coastguard Worker int TCPServerSocket::AdoptSocket(SocketDescriptor socket) {
30*6777b538SAndroid Build Coastguard Worker adopted_opened_socket_ = true;
31*6777b538SAndroid Build Coastguard Worker return socket_->AdoptUnconnectedSocket(socket);
32*6777b538SAndroid Build Coastguard Worker }
33*6777b538SAndroid Build Coastguard Worker
34*6777b538SAndroid Build Coastguard Worker TCPServerSocket::~TCPServerSocket() = default;
35*6777b538SAndroid Build Coastguard Worker
Listen(const IPEndPoint & address,int backlog,std::optional<bool> ipv6_only)36*6777b538SAndroid Build Coastguard Worker int TCPServerSocket::Listen(const IPEndPoint& address,
37*6777b538SAndroid Build Coastguard Worker int backlog,
38*6777b538SAndroid Build Coastguard Worker std::optional<bool> ipv6_only) {
39*6777b538SAndroid Build Coastguard Worker int result = OK;
40*6777b538SAndroid Build Coastguard Worker if (!adopted_opened_socket_) {
41*6777b538SAndroid Build Coastguard Worker result = socket_->Open(address.GetFamily());
42*6777b538SAndroid Build Coastguard Worker if (result != OK) {
43*6777b538SAndroid Build Coastguard Worker return result;
44*6777b538SAndroid Build Coastguard Worker }
45*6777b538SAndroid Build Coastguard Worker }
46*6777b538SAndroid Build Coastguard Worker
47*6777b538SAndroid Build Coastguard Worker if (ipv6_only.has_value()) {
48*6777b538SAndroid Build Coastguard Worker CHECK_EQ(address.address(), net::IPAddress::IPv6AllZeros());
49*6777b538SAndroid Build Coastguard Worker result = socket_->SetIPv6Only(*ipv6_only);
50*6777b538SAndroid Build Coastguard Worker if (result != OK) {
51*6777b538SAndroid Build Coastguard Worker socket_->Close();
52*6777b538SAndroid Build Coastguard Worker return result;
53*6777b538SAndroid Build Coastguard Worker }
54*6777b538SAndroid Build Coastguard Worker }
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker result = socket_->SetDefaultOptionsForServer();
57*6777b538SAndroid Build Coastguard Worker if (result != OK) {
58*6777b538SAndroid Build Coastguard Worker socket_->Close();
59*6777b538SAndroid Build Coastguard Worker return result;
60*6777b538SAndroid Build Coastguard Worker }
61*6777b538SAndroid Build Coastguard Worker
62*6777b538SAndroid Build Coastguard Worker result = socket_->Bind(address);
63*6777b538SAndroid Build Coastguard Worker if (result != OK) {
64*6777b538SAndroid Build Coastguard Worker socket_->Close();
65*6777b538SAndroid Build Coastguard Worker return result;
66*6777b538SAndroid Build Coastguard Worker }
67*6777b538SAndroid Build Coastguard Worker
68*6777b538SAndroid Build Coastguard Worker result = socket_->Listen(backlog);
69*6777b538SAndroid Build Coastguard Worker if (result != OK) {
70*6777b538SAndroid Build Coastguard Worker socket_->Close();
71*6777b538SAndroid Build Coastguard Worker return result;
72*6777b538SAndroid Build Coastguard Worker }
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard Worker return OK;
75*6777b538SAndroid Build Coastguard Worker }
76*6777b538SAndroid Build Coastguard Worker
GetLocalAddress(IPEndPoint * address) const77*6777b538SAndroid Build Coastguard Worker int TCPServerSocket::GetLocalAddress(IPEndPoint* address) const {
78*6777b538SAndroid Build Coastguard Worker return socket_->GetLocalAddress(address);
79*6777b538SAndroid Build Coastguard Worker }
80*6777b538SAndroid Build Coastguard Worker
Accept(std::unique_ptr<StreamSocket> * socket,CompletionOnceCallback callback)81*6777b538SAndroid Build Coastguard Worker int TCPServerSocket::Accept(std::unique_ptr<StreamSocket>* socket,
82*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback) {
83*6777b538SAndroid Build Coastguard Worker return Accept(socket, std::move(callback), nullptr);
84*6777b538SAndroid Build Coastguard Worker }
85*6777b538SAndroid Build Coastguard Worker
Accept(std::unique_ptr<StreamSocket> * socket,CompletionOnceCallback callback,IPEndPoint * peer_address)86*6777b538SAndroid Build Coastguard Worker int TCPServerSocket::Accept(std::unique_ptr<StreamSocket>* socket,
87*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback callback,
88*6777b538SAndroid Build Coastguard Worker IPEndPoint* peer_address) {
89*6777b538SAndroid Build Coastguard Worker DCHECK(socket);
90*6777b538SAndroid Build Coastguard Worker DCHECK(!callback.is_null());
91*6777b538SAndroid Build Coastguard Worker
92*6777b538SAndroid Build Coastguard Worker if (pending_accept_) {
93*6777b538SAndroid Build Coastguard Worker NOTREACHED();
94*6777b538SAndroid Build Coastguard Worker return ERR_UNEXPECTED;
95*6777b538SAndroid Build Coastguard Worker }
96*6777b538SAndroid Build Coastguard Worker
97*6777b538SAndroid Build Coastguard Worker // It is safe to use base::Unretained(this). |socket_| is owned by this class,
98*6777b538SAndroid Build Coastguard Worker // and the callback won't be run after |socket_| is destroyed.
99*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback accept_callback = base::BindOnce(
100*6777b538SAndroid Build Coastguard Worker &TCPServerSocket::OnAcceptCompleted, base::Unretained(this), socket,
101*6777b538SAndroid Build Coastguard Worker peer_address, std::move(callback));
102*6777b538SAndroid Build Coastguard Worker int result = socket_->Accept(&accepted_socket_, &accepted_address_,
103*6777b538SAndroid Build Coastguard Worker std::move(accept_callback));
104*6777b538SAndroid Build Coastguard Worker if (result != ERR_IO_PENDING) {
105*6777b538SAndroid Build Coastguard Worker // |accept_callback| won't be called so we need to run
106*6777b538SAndroid Build Coastguard Worker // ConvertAcceptedSocket() ourselves in order to do the conversion from
107*6777b538SAndroid Build Coastguard Worker // |accepted_socket_| to |socket|.
108*6777b538SAndroid Build Coastguard Worker result = ConvertAcceptedSocket(result, socket, peer_address);
109*6777b538SAndroid Build Coastguard Worker } else {
110*6777b538SAndroid Build Coastguard Worker pending_accept_ = true;
111*6777b538SAndroid Build Coastguard Worker }
112*6777b538SAndroid Build Coastguard Worker
113*6777b538SAndroid Build Coastguard Worker return result;
114*6777b538SAndroid Build Coastguard Worker }
115*6777b538SAndroid Build Coastguard Worker
DetachFromThread()116*6777b538SAndroid Build Coastguard Worker void TCPServerSocket::DetachFromThread() {
117*6777b538SAndroid Build Coastguard Worker socket_->DetachFromThread();
118*6777b538SAndroid Build Coastguard Worker }
119*6777b538SAndroid Build Coastguard Worker
ConvertAcceptedSocket(int result,std::unique_ptr<StreamSocket> * output_accepted_socket,IPEndPoint * output_accepted_address)120*6777b538SAndroid Build Coastguard Worker int TCPServerSocket::ConvertAcceptedSocket(
121*6777b538SAndroid Build Coastguard Worker int result,
122*6777b538SAndroid Build Coastguard Worker std::unique_ptr<StreamSocket>* output_accepted_socket,
123*6777b538SAndroid Build Coastguard Worker IPEndPoint* output_accepted_address) {
124*6777b538SAndroid Build Coastguard Worker // Make sure the TCPSocket object is destroyed in any case.
125*6777b538SAndroid Build Coastguard Worker std::unique_ptr<TCPSocket> temp_accepted_socket(std::move(accepted_socket_));
126*6777b538SAndroid Build Coastguard Worker if (result != OK)
127*6777b538SAndroid Build Coastguard Worker return result;
128*6777b538SAndroid Build Coastguard Worker
129*6777b538SAndroid Build Coastguard Worker if (output_accepted_address)
130*6777b538SAndroid Build Coastguard Worker *output_accepted_address = accepted_address_;
131*6777b538SAndroid Build Coastguard Worker
132*6777b538SAndroid Build Coastguard Worker *output_accepted_socket = std::make_unique<TCPClientSocket>(
133*6777b538SAndroid Build Coastguard Worker std::move(temp_accepted_socket), accepted_address_);
134*6777b538SAndroid Build Coastguard Worker
135*6777b538SAndroid Build Coastguard Worker return OK;
136*6777b538SAndroid Build Coastguard Worker }
137*6777b538SAndroid Build Coastguard Worker
OnAcceptCompleted(std::unique_ptr<StreamSocket> * output_accepted_socket,IPEndPoint * output_accepted_address,CompletionOnceCallback forward_callback,int result)138*6777b538SAndroid Build Coastguard Worker void TCPServerSocket::OnAcceptCompleted(
139*6777b538SAndroid Build Coastguard Worker std::unique_ptr<StreamSocket>* output_accepted_socket,
140*6777b538SAndroid Build Coastguard Worker IPEndPoint* output_accepted_address,
141*6777b538SAndroid Build Coastguard Worker CompletionOnceCallback forward_callback,
142*6777b538SAndroid Build Coastguard Worker int result) {
143*6777b538SAndroid Build Coastguard Worker result = ConvertAcceptedSocket(result, output_accepted_socket,
144*6777b538SAndroid Build Coastguard Worker output_accepted_address);
145*6777b538SAndroid Build Coastguard Worker pending_accept_ = false;
146*6777b538SAndroid Build Coastguard Worker std::move(forward_callback).Run(result);
147*6777b538SAndroid Build Coastguard Worker }
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker } // namespace net
150