1
#include "source/common/quic/envoy_quic_server_connection.h"
2

            
3
#include <memory>
4

            
5
#include "source/common/network/listen_socket_impl.h"
6
#include "source/common/quic/envoy_quic_utils.h"
7
#include "source/common/quic/quic_io_handle_wrapper.h"
8

            
9
#include "quiche/quic/core/quic_packet_writer_wrapper.h"
10
#include "quiche/quic/core/quic_packets.h"
11

            
12
namespace Envoy {
13
namespace Quic {
14

            
15
namespace {
16
std::unique_ptr<quic::QuicPacketWriterWrapper>
17
wrapWriter(quic::QuicPacketWriter* writer,
18
3036
           quic::QuicPacketWriterWrapper::OnWriteDoneCallback on_write_done) {
19
3036
  auto wrapper = std::make_unique<quic::QuicPacketWriterWrapper>();
20
3036
  wrapper->set_non_owning_writer(writer);
21
3036
  wrapper->set_on_write_done(std::move(on_write_done));
22
3036
  return wrapper;
23
3036
}
24
} // namespace
25

            
26
EnvoyQuicServerConnection::EnvoyQuicServerConnection(
27
    const quic::QuicConnectionId& server_connection_id,
28
    quic::QuicSocketAddress initial_self_address, quic::QuicSocketAddress initial_peer_address,
29
    quic::QuicConnectionHelperInterface& helper, quic::QuicAlarmFactory& alarm_factory,
30
    quic::QuicPacketWriter* writer, const quic::ParsedQuicVersionVector& supported_versions,
31
    Network::ConnectionSocketPtr connection_socket, quic::ConnectionIdGeneratorInterface& generator,
32
    std::unique_ptr<QuicListenerFilterManagerImpl> listener_filter_manager)
33
3036
    : quic::QuicConnection(
34
3036
          server_connection_id, initial_self_address, initial_peer_address, &helper, &alarm_factory,
35
          // Wrap the packet writer to get notified when a packet is written.
36
3036
          wrapWriter(writer,
37
458103
                     [this](size_t packet_size, const quic::WriteResult& result) {
38
458074
                       OnWritePacketDone(packet_size, result);
39
458074
                     })
40
3036
              .release(),
41
3036
          /*owns_writer=*/true, quic::Perspective::IS_SERVER, supported_versions, generator),
42
3036
      QuicNetworkConnection(std::move(connection_socket)),
43
3036
      listener_filter_manager_(std::move(listener_filter_manager)) {
44
3036
#ifndef WIN32
45
  // Defer sending while processing UDP packets till the end of the current event loop to optimize
46
  // UDP GSO sendmsg efficiency. But this optimization causes some test failures under Windows,
47
  // and Windows doesn't support GSO, do not apply this optimization on Windows.
48
  // TODO(#22976) Figure out if this is needed on Windows.
49
3036
  set_defer_send_in_response_to_packets(GetQuicFlag(quic_defer_send_in_response));
50
3036
#endif
51
3036
}
52

            
53
241010
bool EnvoyQuicServerConnection::OnPacketHeader(const quic::QuicPacketHeader& header) {
54
241010
  quic::QuicSocketAddress old_self_address = self_address();
55
241010
  if (!quic::QuicConnection::OnPacketHeader(header)) {
56
2
    return false;
57
2
  }
58
241008
  if (old_self_address == self_address()) {
59
241008
    return true;
60
241008
  }
61
  // Update local address if QUICHE has updated the self address.
62
  ASSERT(self_address().IsInitialized());
63
  connectionSocket()->connectionInfoProvider().setLocalAddress(
64
      quicAddressToEnvoyAddressInstance(self_address()));
65

            
66
  return true;
67
241008
}
68

            
69
void EnvoyQuicServerConnection::OnWritePacketDone(size_t packet_size,
70
458074
                                                  const quic::WriteResult& /*result*/) {
71
458074
  if (hasConnectionStats()) {
72
105369
    connectionStats().write_total_.add(packet_size);
73
105369
  }
74
458074
}
75

            
76
19901
void EnvoyQuicServerConnection::OnCanWrite() {
77
19901
  quic::QuicConnection::OnCanWrite();
78
19901
  onWriteEventDone();
79
19901
}
80

            
81
void EnvoyQuicServerConnection::ProcessUdpPacket(const quic::QuicSocketAddress& self_address,
82
                                                 const quic::QuicSocketAddress& peer_address,
83
238152
                                                 const quic::QuicReceivedPacket& packet) {
84
238152
  if (!first_packet_received_) {
85
2971
    if (listener_filter_manager_ != nullptr) {
86
2971
      listener_filter_manager_->onFirstPacketReceived(packet);
87
2971
    }
88
2971
    first_packet_received_ = true;
89
2971
  }
90

            
91
238152
  quic::QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
92
238152
};
93

            
94
23
void EnvoyQuicServerConnection::OnEffectivePeerMigrationValidated(bool is_migration_linkable) {
95
23
  quic::QuicConnection::OnEffectivePeerMigrationValidated(is_migration_linkable);
96
23
  if (listener_filter_manager_ != nullptr && networkConnection() != nullptr) {
97
    // This connection might become closed after this call.
98
23
    listener_filter_manager_->onPeerAddressChanged(effective_peer_address(), *networkConnection());
99
23
  }
100
23
}
101

            
102
} // namespace Quic
103
} // namespace Envoy