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/testing/fake_quic_connection_factory.h"
6
7 #include <algorithm>
8 #include <memory>
9
10 #include "util/osp_logging.h"
11
12 namespace openscreen {
13 namespace osp {
14
FakeQuicConnectionFactoryBridge(const IPEndpoint & controller_endpoint)15 FakeQuicConnectionFactoryBridge::FakeQuicConnectionFactoryBridge(
16 const IPEndpoint& controller_endpoint)
17 : controller_endpoint_(controller_endpoint) {}
18
OnConnectionClosed(QuicConnection * connection)19 void FakeQuicConnectionFactoryBridge::OnConnectionClosed(
20 QuicConnection* connection) {
21 if (connection == connections_.controller) {
22 connections_.controller = nullptr;
23 return;
24 } else if (connection == connections_.receiver) {
25 connections_.receiver = nullptr;
26 return;
27 }
28 OSP_DCHECK(false) << "reporting an unknown connection as closed";
29 }
30
OnOutgoingStream(QuicConnection * connection,QuicStream * stream)31 void FakeQuicConnectionFactoryBridge::OnOutgoingStream(
32 QuicConnection* connection,
33 QuicStream* stream) {
34 FakeQuicConnection* remote_connection = nullptr;
35 if (connection == connections_.controller) {
36 remote_connection = connections_.receiver;
37 } else if (connection == connections_.receiver) {
38 remote_connection = connections_.controller;
39 }
40
41 if (remote_connection) {
42 remote_connection->delegate()->OnIncomingStream(
43 remote_connection->id(), remote_connection->MakeIncomingStream());
44 }
45 }
46
SetServerDelegate(QuicConnectionFactory::ServerDelegate * delegate,const IPEndpoint & endpoint)47 void FakeQuicConnectionFactoryBridge::SetServerDelegate(
48 QuicConnectionFactory::ServerDelegate* delegate,
49 const IPEndpoint& endpoint) {
50 OSP_DCHECK(!delegate_ || !delegate);
51 delegate_ = delegate;
52 receiver_endpoint_ = endpoint;
53 }
54
RunTasks(bool is_client)55 void FakeQuicConnectionFactoryBridge::RunTasks(bool is_client) {
56 bool* idle_flag = is_client ? &client_idle_ : &server_idle_;
57 *idle_flag = true;
58
59 if (!connections_.controller || !connections_.receiver) {
60 return;
61 }
62
63 if (connections_pending_) {
64 *idle_flag = false;
65 connections_.receiver->delegate()->OnCryptoHandshakeComplete(
66 connections_.receiver->id());
67 connections_.controller->delegate()->OnCryptoHandshakeComplete(
68 connections_.controller->id());
69 connections_pending_ = false;
70 return;
71 }
72
73 const size_t num_streams = connections_.controller->streams().size();
74 OSP_CHECK_EQ(num_streams, connections_.receiver->streams().size());
75
76 auto stream_it_pair =
77 std::make_pair(connections_.controller->streams().begin(),
78 connections_.receiver->streams().begin());
79
80 for (size_t i = 0; i < num_streams; ++i) {
81 auto* controller_stream = stream_it_pair.first->second;
82 auto* receiver_stream = stream_it_pair.second->second;
83
84 std::vector<uint8_t> written_data = controller_stream->TakeWrittenData();
85 OSP_DCHECK(controller_stream->TakeReceivedData().empty());
86
87 if (!written_data.empty()) {
88 *idle_flag = false;
89 receiver_stream->delegate()->OnReceived(
90 receiver_stream, reinterpret_cast<const char*>(written_data.data()),
91 written_data.size());
92 }
93
94 written_data = receiver_stream->TakeWrittenData();
95 OSP_DCHECK(receiver_stream->TakeReceivedData().empty());
96
97 if (written_data.size()) {
98 *idle_flag = false;
99 controller_stream->delegate()->OnReceived(
100 controller_stream, reinterpret_cast<const char*>(written_data.data()),
101 written_data.size());
102 }
103
104 // Close the read end for closed write ends
105 if (controller_stream->write_end_closed()) {
106 receiver_stream->CloseReadEnd();
107 }
108 if (receiver_stream->write_end_closed()) {
109 controller_stream->CloseReadEnd();
110 }
111
112 if (controller_stream->both_ends_closed() &&
113 receiver_stream->both_ends_closed()) {
114 controller_stream->delegate()->OnClose(controller_stream->id());
115 receiver_stream->delegate()->OnClose(receiver_stream->id());
116
117 controller_stream->delegate()->OnReceived(controller_stream, nullptr, 0);
118 receiver_stream->delegate()->OnReceived(receiver_stream, nullptr, 0);
119
120 stream_it_pair.first =
121 connections_.controller->streams().erase(stream_it_pair.first);
122 stream_it_pair.second =
123 connections_.receiver->streams().erase(stream_it_pair.second);
124 } else {
125 // The stream pair must always be advanced at the same time.
126 ++stream_it_pair.first;
127 ++stream_it_pair.second;
128 }
129 }
130 }
131
Connect(const IPEndpoint & endpoint,QuicConnection::Delegate * connection_delegate)132 std::unique_ptr<QuicConnection> FakeQuicConnectionFactoryBridge::Connect(
133 const IPEndpoint& endpoint,
134 QuicConnection::Delegate* connection_delegate) {
135 if (endpoint != receiver_endpoint_) {
136 return nullptr;
137 }
138
139 OSP_DCHECK(!connections_.controller);
140 OSP_DCHECK(!connections_.receiver);
141 auto controller_connection = std::make_unique<FakeQuicConnection>(
142 this, next_connection_id_++, connection_delegate);
143 connections_.controller = controller_connection.get();
144
145 auto receiver_connection = std::make_unique<FakeQuicConnection>(
146 this, next_connection_id_++,
147 delegate_->NextConnectionDelegate(controller_endpoint_));
148 connections_.receiver = receiver_connection.get();
149 delegate_->OnIncomingConnection(std::move(receiver_connection));
150 return controller_connection;
151 }
152
FakeClientQuicConnectionFactory(FakeQuicConnectionFactoryBridge * bridge)153 FakeClientQuicConnectionFactory::FakeClientQuicConnectionFactory(
154 FakeQuicConnectionFactoryBridge* bridge)
155 : bridge_(bridge) {}
156 FakeClientQuicConnectionFactory::~FakeClientQuicConnectionFactory() = default;
157
SetServerDelegate(ServerDelegate * delegate,const std::vector<IPEndpoint> & endpoints)158 void FakeClientQuicConnectionFactory::SetServerDelegate(
159 ServerDelegate* delegate,
160 const std::vector<IPEndpoint>& endpoints) {
161 OSP_DCHECK(false) << "don't call SetServerDelegate from QuicClient side";
162 }
163
Connect(const IPEndpoint & endpoint,QuicConnection::Delegate * connection_delegate)164 std::unique_ptr<QuicConnection> FakeClientQuicConnectionFactory::Connect(
165 const IPEndpoint& endpoint,
166 QuicConnection::Delegate* connection_delegate) {
167 return bridge_->Connect(endpoint, connection_delegate);
168 }
169
OnError(UdpSocket * socket,Error error)170 void FakeClientQuicConnectionFactory::OnError(UdpSocket* socket, Error error) {
171 OSP_UNIMPLEMENTED();
172 }
173
OnSendError(UdpSocket * socket,Error error)174 void FakeClientQuicConnectionFactory::OnSendError(UdpSocket* socket,
175 Error error) {
176 OSP_UNIMPLEMENTED();
177 }
178
OnRead(UdpSocket * socket,ErrorOr<UdpPacket> packet)179 void FakeClientQuicConnectionFactory::OnRead(UdpSocket* socket,
180 ErrorOr<UdpPacket> packet) {
181 bridge_->RunTasks(true);
182 idle_ = bridge_->client_idle();
183 }
184
FakeServerQuicConnectionFactory(FakeQuicConnectionFactoryBridge * bridge)185 FakeServerQuicConnectionFactory::FakeServerQuicConnectionFactory(
186 FakeQuicConnectionFactoryBridge* bridge)
187 : bridge_(bridge) {}
188 FakeServerQuicConnectionFactory::~FakeServerQuicConnectionFactory() = default;
189
SetServerDelegate(ServerDelegate * delegate,const std::vector<IPEndpoint> & endpoints)190 void FakeServerQuicConnectionFactory::SetServerDelegate(
191 ServerDelegate* delegate,
192 const std::vector<IPEndpoint>& endpoints) {
193 if (delegate) {
194 OSP_DCHECK_EQ(1u, endpoints.size())
195 << "fake bridge doesn't support multiple server endpoints";
196 }
197 bridge_->SetServerDelegate(delegate,
198 endpoints.empty() ? IPEndpoint{} : endpoints[0]);
199 }
200
Connect(const IPEndpoint & endpoint,QuicConnection::Delegate * connection_delegate)201 std::unique_ptr<QuicConnection> FakeServerQuicConnectionFactory::Connect(
202 const IPEndpoint& endpoint,
203 QuicConnection::Delegate* connection_delegate) {
204 OSP_DCHECK(false) << "don't call Connect() from QuicServer side";
205 return nullptr;
206 }
207
OnError(UdpSocket * socket,Error error)208 void FakeServerQuicConnectionFactory::OnError(UdpSocket* socket, Error error) {
209 OSP_UNIMPLEMENTED();
210 }
211
OnSendError(UdpSocket * socket,Error error)212 void FakeServerQuicConnectionFactory::OnSendError(UdpSocket* socket,
213 Error error) {
214 OSP_UNIMPLEMENTED();
215 }
216
OnRead(UdpSocket * socket,ErrorOr<UdpPacket> packet)217 void FakeServerQuicConnectionFactory::OnRead(UdpSocket* socket,
218 ErrorOr<UdpPacket> packet) {
219 bridge_->RunTasks(false);
220 idle_ = bridge_->server_idle();
221 }
222
223 } // namespace osp
224 } // namespace openscreen
225