xref: /aosp_15_r20/external/openscreen/osp/impl/quic/quic_server.cc (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2018 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #include "osp/impl/quic/quic_server.h"
6*3f982cf4SFabien Sanglard 
7*3f982cf4SFabien Sanglard #include <functional>
8*3f982cf4SFabien Sanglard #include <memory>
9*3f982cf4SFabien Sanglard 
10*3f982cf4SFabien Sanglard #include "platform/api/task_runner.h"
11*3f982cf4SFabien Sanglard #include "platform/api/time.h"
12*3f982cf4SFabien Sanglard #include "util/osp_logging.h"
13*3f982cf4SFabien Sanglard 
14*3f982cf4SFabien Sanglard namespace openscreen {
15*3f982cf4SFabien Sanglard namespace osp {
16*3f982cf4SFabien Sanglard 
QuicServer(const ServerConfig & config,MessageDemuxer * demuxer,std::unique_ptr<QuicConnectionFactory> connection_factory,ProtocolConnectionServer::Observer * observer,ClockNowFunctionPtr now_function,TaskRunner * task_runner)17*3f982cf4SFabien Sanglard QuicServer::QuicServer(
18*3f982cf4SFabien Sanglard     const ServerConfig& config,
19*3f982cf4SFabien Sanglard     MessageDemuxer* demuxer,
20*3f982cf4SFabien Sanglard     std::unique_ptr<QuicConnectionFactory> connection_factory,
21*3f982cf4SFabien Sanglard     ProtocolConnectionServer::Observer* observer,
22*3f982cf4SFabien Sanglard     ClockNowFunctionPtr now_function,
23*3f982cf4SFabien Sanglard     TaskRunner* task_runner)
24*3f982cf4SFabien Sanglard     : ProtocolConnectionServer(demuxer, observer),
25*3f982cf4SFabien Sanglard       connection_endpoints_(config.connection_endpoints),
26*3f982cf4SFabien Sanglard       connection_factory_(std::move(connection_factory)),
27*3f982cf4SFabien Sanglard       cleanup_alarm_(now_function, task_runner) {}
28*3f982cf4SFabien Sanglard 
~QuicServer()29*3f982cf4SFabien Sanglard QuicServer::~QuicServer() {
30*3f982cf4SFabien Sanglard   CloseAllConnections();
31*3f982cf4SFabien Sanglard }
32*3f982cf4SFabien Sanglard 
Start()33*3f982cf4SFabien Sanglard bool QuicServer::Start() {
34*3f982cf4SFabien Sanglard   if (state_ != State::kStopped)
35*3f982cf4SFabien Sanglard     return false;
36*3f982cf4SFabien Sanglard   state_ = State::kRunning;
37*3f982cf4SFabien Sanglard   connection_factory_->SetServerDelegate(this, connection_endpoints_);
38*3f982cf4SFabien Sanglard   Cleanup();  // Start periodic clean-ups.
39*3f982cf4SFabien Sanglard   observer_->OnRunning();
40*3f982cf4SFabien Sanglard   return true;
41*3f982cf4SFabien Sanglard }
42*3f982cf4SFabien Sanglard 
Stop()43*3f982cf4SFabien Sanglard bool QuicServer::Stop() {
44*3f982cf4SFabien Sanglard   if (state_ != State::kRunning && state_ != State::kSuspended)
45*3f982cf4SFabien Sanglard     return false;
46*3f982cf4SFabien Sanglard   connection_factory_->SetServerDelegate(nullptr, {});
47*3f982cf4SFabien Sanglard   CloseAllConnections();
48*3f982cf4SFabien Sanglard   state_ = State::kStopped;
49*3f982cf4SFabien Sanglard   Cleanup();  // Final clean-up.
50*3f982cf4SFabien Sanglard   observer_->OnStopped();
51*3f982cf4SFabien Sanglard   return true;
52*3f982cf4SFabien Sanglard }
53*3f982cf4SFabien Sanglard 
Suspend()54*3f982cf4SFabien Sanglard bool QuicServer::Suspend() {
55*3f982cf4SFabien Sanglard   // TODO(btolsch): QuicStreams should either buffer or reject writes.
56*3f982cf4SFabien Sanglard   if (state_ != State::kRunning)
57*3f982cf4SFabien Sanglard     return false;
58*3f982cf4SFabien Sanglard   state_ = State::kSuspended;
59*3f982cf4SFabien Sanglard   observer_->OnSuspended();
60*3f982cf4SFabien Sanglard   return true;
61*3f982cf4SFabien Sanglard }
62*3f982cf4SFabien Sanglard 
Resume()63*3f982cf4SFabien Sanglard bool QuicServer::Resume() {
64*3f982cf4SFabien Sanglard   if (state_ != State::kSuspended)
65*3f982cf4SFabien Sanglard     return false;
66*3f982cf4SFabien Sanglard   state_ = State::kRunning;
67*3f982cf4SFabien Sanglard   observer_->OnRunning();
68*3f982cf4SFabien Sanglard   return true;
69*3f982cf4SFabien Sanglard }
70*3f982cf4SFabien Sanglard 
Cleanup()71*3f982cf4SFabien Sanglard void QuicServer::Cleanup() {
72*3f982cf4SFabien Sanglard   for (auto& entry : connections_)
73*3f982cf4SFabien Sanglard     entry.second.delegate->DestroyClosedStreams();
74*3f982cf4SFabien Sanglard 
75*3f982cf4SFabien Sanglard   for (uint64_t endpoint_id : delete_connections_) {
76*3f982cf4SFabien Sanglard     auto it = connections_.find(endpoint_id);
77*3f982cf4SFabien Sanglard     if (it != connections_.end()) {
78*3f982cf4SFabien Sanglard       connections_.erase(it);
79*3f982cf4SFabien Sanglard     }
80*3f982cf4SFabien Sanglard   }
81*3f982cf4SFabien Sanglard   delete_connections_.clear();
82*3f982cf4SFabien Sanglard 
83*3f982cf4SFabien Sanglard   constexpr Clock::duration kQuicCleanupPeriod = std::chrono::milliseconds(500);
84*3f982cf4SFabien Sanglard   if (state_ != State::kStopped) {
85*3f982cf4SFabien Sanglard     cleanup_alarm_.ScheduleFromNow([this] { Cleanup(); }, kQuicCleanupPeriod);
86*3f982cf4SFabien Sanglard   }
87*3f982cf4SFabien Sanglard }
88*3f982cf4SFabien Sanglard 
CreateProtocolConnection(uint64_t endpoint_id)89*3f982cf4SFabien Sanglard std::unique_ptr<ProtocolConnection> QuicServer::CreateProtocolConnection(
90*3f982cf4SFabien Sanglard     uint64_t endpoint_id) {
91*3f982cf4SFabien Sanglard   if (state_ != State::kRunning) {
92*3f982cf4SFabien Sanglard     return nullptr;
93*3f982cf4SFabien Sanglard   }
94*3f982cf4SFabien Sanglard   auto connection_entry = connections_.find(endpoint_id);
95*3f982cf4SFabien Sanglard   if (connection_entry == connections_.end()) {
96*3f982cf4SFabien Sanglard     return nullptr;
97*3f982cf4SFabien Sanglard   }
98*3f982cf4SFabien Sanglard   return QuicProtocolConnection::FromExisting(
99*3f982cf4SFabien Sanglard       this, connection_entry->second.connection.get(),
100*3f982cf4SFabien Sanglard       connection_entry->second.delegate.get(), endpoint_id);
101*3f982cf4SFabien Sanglard }
102*3f982cf4SFabien Sanglard 
OnConnectionDestroyed(QuicProtocolConnection * connection)103*3f982cf4SFabien Sanglard void QuicServer::OnConnectionDestroyed(QuicProtocolConnection* connection) {
104*3f982cf4SFabien Sanglard   if (!connection->stream())
105*3f982cf4SFabien Sanglard     return;
106*3f982cf4SFabien Sanglard 
107*3f982cf4SFabien Sanglard   auto connection_entry = connections_.find(connection->endpoint_id());
108*3f982cf4SFabien Sanglard   if (connection_entry == connections_.end())
109*3f982cf4SFabien Sanglard     return;
110*3f982cf4SFabien Sanglard 
111*3f982cf4SFabien Sanglard   connection_entry->second.delegate->DropProtocolConnection(connection);
112*3f982cf4SFabien Sanglard }
113*3f982cf4SFabien Sanglard 
OnCryptoHandshakeComplete(ServiceConnectionDelegate * delegate,uint64_t connection_id)114*3f982cf4SFabien Sanglard uint64_t QuicServer::OnCryptoHandshakeComplete(
115*3f982cf4SFabien Sanglard     ServiceConnectionDelegate* delegate,
116*3f982cf4SFabien Sanglard     uint64_t connection_id) {
117*3f982cf4SFabien Sanglard   OSP_DCHECK_EQ(state_, State::kRunning);
118*3f982cf4SFabien Sanglard   const IPEndpoint& endpoint = delegate->endpoint();
119*3f982cf4SFabien Sanglard   auto pending_entry = pending_connections_.find(endpoint);
120*3f982cf4SFabien Sanglard   if (pending_entry == pending_connections_.end())
121*3f982cf4SFabien Sanglard     return 0;
122*3f982cf4SFabien Sanglard   ServiceConnectionData connection_data = std::move(pending_entry->second);
123*3f982cf4SFabien Sanglard   pending_connections_.erase(pending_entry);
124*3f982cf4SFabien Sanglard   uint64_t endpoint_id = next_endpoint_id_++;
125*3f982cf4SFabien Sanglard   endpoint_map_[endpoint] = endpoint_id;
126*3f982cf4SFabien Sanglard   connections_.emplace(endpoint_id, std::move(connection_data));
127*3f982cf4SFabien Sanglard   return endpoint_id;
128*3f982cf4SFabien Sanglard }
129*3f982cf4SFabien Sanglard 
OnIncomingStream(std::unique_ptr<QuicProtocolConnection> connection)130*3f982cf4SFabien Sanglard void QuicServer::OnIncomingStream(
131*3f982cf4SFabien Sanglard     std::unique_ptr<QuicProtocolConnection> connection) {
132*3f982cf4SFabien Sanglard   OSP_DCHECK_EQ(state_, State::kRunning);
133*3f982cf4SFabien Sanglard   observer_->OnIncomingConnection(std::move(connection));
134*3f982cf4SFabien Sanglard }
135*3f982cf4SFabien Sanglard 
OnConnectionClosed(uint64_t endpoint_id,uint64_t connection_id)136*3f982cf4SFabien Sanglard void QuicServer::OnConnectionClosed(uint64_t endpoint_id,
137*3f982cf4SFabien Sanglard                                     uint64_t connection_id) {
138*3f982cf4SFabien Sanglard   OSP_DCHECK_EQ(state_, State::kRunning);
139*3f982cf4SFabien Sanglard   auto connection_entry = connections_.find(endpoint_id);
140*3f982cf4SFabien Sanglard   if (connection_entry == connections_.end())
141*3f982cf4SFabien Sanglard     return;
142*3f982cf4SFabien Sanglard   delete_connections_.push_back(endpoint_id);
143*3f982cf4SFabien Sanglard 
144*3f982cf4SFabien Sanglard   // TODO(crbug.com/openscreen/42): If we reset request IDs when a connection is
145*3f982cf4SFabien Sanglard   // closed, we might end up re-using request IDs when a new connection is
146*3f982cf4SFabien Sanglard   // created to the same endpoint.
147*3f982cf4SFabien Sanglard   endpoint_request_ids_.ResetRequestId(endpoint_id);
148*3f982cf4SFabien Sanglard }
149*3f982cf4SFabien Sanglard 
OnDataReceived(uint64_t endpoint_id,uint64_t connection_id,const uint8_t * data,size_t data_size)150*3f982cf4SFabien Sanglard void QuicServer::OnDataReceived(uint64_t endpoint_id,
151*3f982cf4SFabien Sanglard                                 uint64_t connection_id,
152*3f982cf4SFabien Sanglard                                 const uint8_t* data,
153*3f982cf4SFabien Sanglard                                 size_t data_size) {
154*3f982cf4SFabien Sanglard   OSP_DCHECK_EQ(state_, State::kRunning);
155*3f982cf4SFabien Sanglard   demuxer_->OnStreamData(endpoint_id, connection_id, data, data_size);
156*3f982cf4SFabien Sanglard }
157*3f982cf4SFabien Sanglard 
CloseAllConnections()158*3f982cf4SFabien Sanglard void QuicServer::CloseAllConnections() {
159*3f982cf4SFabien Sanglard   for (auto& conn : pending_connections_)
160*3f982cf4SFabien Sanglard     conn.second.connection->Close();
161*3f982cf4SFabien Sanglard 
162*3f982cf4SFabien Sanglard   pending_connections_.clear();
163*3f982cf4SFabien Sanglard 
164*3f982cf4SFabien Sanglard   for (auto& conn : connections_)
165*3f982cf4SFabien Sanglard     conn.second.connection->Close();
166*3f982cf4SFabien Sanglard 
167*3f982cf4SFabien Sanglard   connections_.clear();
168*3f982cf4SFabien Sanglard   endpoint_map_.clear();
169*3f982cf4SFabien Sanglard   next_endpoint_id_ = 0;
170*3f982cf4SFabien Sanglard   endpoint_request_ids_.Reset();
171*3f982cf4SFabien Sanglard }
172*3f982cf4SFabien Sanglard 
NextConnectionDelegate(const IPEndpoint & source)173*3f982cf4SFabien Sanglard QuicConnection::Delegate* QuicServer::NextConnectionDelegate(
174*3f982cf4SFabien Sanglard     const IPEndpoint& source) {
175*3f982cf4SFabien Sanglard   OSP_DCHECK_EQ(state_, State::kRunning);
176*3f982cf4SFabien Sanglard   OSP_DCHECK(!pending_connection_delegate_);
177*3f982cf4SFabien Sanglard   pending_connection_delegate_ =
178*3f982cf4SFabien Sanglard       std::make_unique<ServiceConnectionDelegate>(this, source);
179*3f982cf4SFabien Sanglard   return pending_connection_delegate_.get();
180*3f982cf4SFabien Sanglard }
181*3f982cf4SFabien Sanglard 
OnIncomingConnection(std::unique_ptr<QuicConnection> connection)182*3f982cf4SFabien Sanglard void QuicServer::OnIncomingConnection(
183*3f982cf4SFabien Sanglard     std::unique_ptr<QuicConnection> connection) {
184*3f982cf4SFabien Sanglard   OSP_DCHECK_EQ(state_, State::kRunning);
185*3f982cf4SFabien Sanglard   const IPEndpoint& endpoint = pending_connection_delegate_->endpoint();
186*3f982cf4SFabien Sanglard   pending_connections_.emplace(
187*3f982cf4SFabien Sanglard       endpoint, ServiceConnectionData(std::move(connection),
188*3f982cf4SFabien Sanglard                                       std::move(pending_connection_delegate_)));
189*3f982cf4SFabien Sanglard }
190*3f982cf4SFabien Sanglard 
191*3f982cf4SFabien Sanglard }  // namespace osp
192*3f982cf4SFabien Sanglard }  // namespace openscreen
193