xref: /aosp_15_r20/external/openscreen/osp/impl/quic/quic_connection_impl.cc (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1 // Copyright 2018 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 "osp/impl/quic/quic_connection_impl.h"
6 
7 #include <limits>
8 #include <memory>
9 
10 #include "absl/types/optional.h"
11 #include "osp/impl/quic/quic_connection_factory_impl.h"
12 #include "platform/base/error.h"
13 #include "third_party/chromium_quic/src/net/third_party/quic/platform/impl/quic_chromium_clock.h"
14 #include "util/osp_logging.h"
15 #include "util/trace_logging.h"
16 
17 namespace openscreen {
18 namespace osp {
19 
UdpTransport(UdpSocket * socket,const IPEndpoint & destination)20 UdpTransport::UdpTransport(UdpSocket* socket, const IPEndpoint& destination)
21     : socket_(socket), destination_(destination) {
22   OSP_DCHECK(socket_);
23 }
24 
25 UdpTransport::UdpTransport(UdpTransport&&) noexcept = default;
26 UdpTransport::~UdpTransport() = default;
27 
28 UdpTransport& UdpTransport::operator=(UdpTransport&&) noexcept = default;
29 
Write(const char * buffer,size_t buffer_length,const PacketInfo & info)30 int UdpTransport::Write(const char* buffer,
31                         size_t buffer_length,
32                         const PacketInfo& info) {
33   TRACE_SCOPED(TraceCategory::kQuic, "UdpTransport::Write");
34   socket_->SendMessage(buffer, buffer_length, destination_);
35   OSP_DCHECK_LE(buffer_length,
36                 static_cast<size_t>(std::numeric_limits<int>::max()));
37   return static_cast<int>(buffer_length);
38 }
39 
QuicStreamImpl(QuicStream::Delegate * delegate,::quic::QuartcStream * stream)40 QuicStreamImpl::QuicStreamImpl(QuicStream::Delegate* delegate,
41                                ::quic::QuartcStream* stream)
42     : QuicStream(delegate, stream->id()), stream_(stream) {
43   stream_->SetDelegate(this);
44 }
45 
46 QuicStreamImpl::~QuicStreamImpl() = default;
47 
Write(const uint8_t * data,size_t data_size)48 void QuicStreamImpl::Write(const uint8_t* data, size_t data_size) {
49   TRACE_SCOPED(TraceCategory::kQuic, "QuicStreamImpl::Write");
50   OSP_DCHECK(!stream_->write_side_closed());
51   stream_->WriteOrBufferData(
52       ::quic::QuicStringPiece(reinterpret_cast<const char*>(data), data_size),
53       false, nullptr);
54 }
55 
CloseWriteEnd()56 void QuicStreamImpl::CloseWriteEnd() {
57   TRACE_SCOPED(TraceCategory::kQuic, "QuicStreamImpl::CloseWriteEnd");
58   if (!stream_->write_side_closed())
59     stream_->FinishWriting();
60 }
61 
OnReceived(::quic::QuartcStream * stream,const char * data,size_t data_size)62 void QuicStreamImpl::OnReceived(::quic::QuartcStream* stream,
63                                 const char* data,
64                                 size_t data_size) {
65   TRACE_SCOPED(TraceCategory::kQuic, "QuicStreamImpl::OnReceived");
66   delegate_->OnReceived(this, data, data_size);
67 }
68 
OnClose(::quic::QuartcStream * stream)69 void QuicStreamImpl::OnClose(::quic::QuartcStream* stream) {
70   TRACE_SCOPED(TraceCategory::kQuic, "QuicStreamImpl::OnClose");
71   delegate_->OnClose(stream->id());
72 }
73 
OnBufferChanged(::quic::QuartcStream * stream)74 void QuicStreamImpl::OnBufferChanged(::quic::QuartcStream* stream) {}
75 
76 // Passes a received UDP packet to the QUIC implementation.  If this contains
77 // any stream data, it will be passed automatically to the relevant
78 // QuicStream::Delegate objects.
OnRead(UdpSocket * socket,ErrorOr<UdpPacket> data)79 void QuicConnectionImpl::OnRead(UdpSocket* socket, ErrorOr<UdpPacket> data) {
80   TRACE_SCOPED(TraceCategory::kQuic, "QuicConnectionImpl::OnRead");
81   if (data.is_error()) {
82     TRACE_SET_RESULT(data.error());
83     return;
84   }
85 
86   session_->OnTransportReceived(
87       reinterpret_cast<const char*>(data.value().data()), data.value().size());
88 }
89 
OnSendError(UdpSocket * socket,Error error)90 void QuicConnectionImpl::OnSendError(UdpSocket* socket, Error error) {
91   // TODO(crbug.com/openscreen/67): Implement this method.
92   OSP_UNIMPLEMENTED();
93 }
94 
OnError(UdpSocket * socket,Error error)95 void QuicConnectionImpl::OnError(UdpSocket* socket, Error error) {
96   // TODO(crbug.com/openscreen/67): Implement this method.
97   OSP_UNIMPLEMENTED();
98 }
99 
QuicConnectionImpl(QuicConnectionFactoryImpl * parent_factory,QuicConnection::Delegate * delegate,std::unique_ptr<UdpTransport> udp_transport,std::unique_ptr<::quic::QuartcSession> session)100 QuicConnectionImpl::QuicConnectionImpl(
101     QuicConnectionFactoryImpl* parent_factory,
102     QuicConnection::Delegate* delegate,
103     std::unique_ptr<UdpTransport> udp_transport,
104     std::unique_ptr<::quic::QuartcSession> session)
105     : QuicConnection(delegate),
106       parent_factory_(parent_factory),
107       session_(std::move(session)),
108       udp_transport_(std::move(udp_transport)) {
109   TRACE_SCOPED(TraceCategory::kQuic, "QuicConnectionImpl::QuicConnectionImpl");
110   session_->SetDelegate(this);
111   session_->OnTransportCanWrite();
112   session_->StartCryptoHandshake();
113 }
114 
115 QuicConnectionImpl::~QuicConnectionImpl() = default;
116 
MakeOutgoingStream(QuicStream::Delegate * delegate)117 std::unique_ptr<QuicStream> QuicConnectionImpl::MakeOutgoingStream(
118     QuicStream::Delegate* delegate) {
119   TRACE_SCOPED(TraceCategory::kQuic, "QuicConnectionImpl::MakeOutgoingStream");
120   ::quic::QuartcStream* stream = session_->CreateOutgoingDynamicStream();
121   return std::make_unique<QuicStreamImpl>(delegate, stream);
122 }
123 
Close()124 void QuicConnectionImpl::Close() {
125   TRACE_SCOPED(TraceCategory::kQuic, "QuicConnectionImpl::Close");
126   session_->CloseConnection("closed");
127 }
128 
OnCryptoHandshakeComplete()129 void QuicConnectionImpl::OnCryptoHandshakeComplete() {
130   TRACE_SCOPED(TraceCategory::kQuic,
131                "QuicConnectionImpl::OnCryptoHandshakeComplete");
132   delegate_->OnCryptoHandshakeComplete(session_->connection_id());
133 }
134 
OnIncomingStream(::quic::QuartcStream * stream)135 void QuicConnectionImpl::OnIncomingStream(::quic::QuartcStream* stream) {
136   TRACE_SCOPED(TraceCategory::kQuic, "QuicConnectionImpl::OnIncomingStream");
137   auto public_stream = std::make_unique<QuicStreamImpl>(
138       delegate_->NextStreamDelegate(session_->connection_id(), stream->id()),
139       stream);
140   streams_.push_back(public_stream.get());
141   delegate_->OnIncomingStream(session_->connection_id(),
142                               std::move(public_stream));
143 }
144 
OnConnectionClosed(::quic::QuicErrorCode error_code,const::quic::QuicString & error_details,::quic::ConnectionCloseSource source)145 void QuicConnectionImpl::OnConnectionClosed(
146     ::quic::QuicErrorCode error_code,
147     const ::quic::QuicString& error_details,
148     ::quic::ConnectionCloseSource source) {
149   TRACE_SCOPED(TraceCategory::kQuic, "QuicConnectionImpl::OnConnectionClosed");
150   parent_factory_->OnConnectionClosed(this);
151   delegate_->OnConnectionClosed(session_->connection_id());
152 }
153 
154 }  // namespace osp
155 }  // namespace openscreen
156