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/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