xref: /aosp_15_r20/external/cronet/net/socket/tcp_server_socket.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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