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
3038
           quic::QuicPacketWriterWrapper::OnWriteDoneCallback on_write_done) {
19
3038
  auto wrapper = std::make_unique<quic::QuicPacketWriterWrapper>();
20
3038
  wrapper->set_non_owning_writer(writer);
21
3038
  wrapper->set_on_write_done(std::move(on_write_done));
22
3038
  return wrapper;
23
3038
}
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
3038
    : quic::QuicConnection(
34
3038
          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
3038
          wrapWriter(writer,
37
463549
                     [this](size_t packet_size, const quic::WriteResult& result) {
38
463520
                       OnWritePacketDone(packet_size, result);
39
463520
                     })
40
3038
              .release(),
41
3038
          /*owns_writer=*/true, quic::Perspective::IS_SERVER, supported_versions, generator),
42
3038
      QuicNetworkConnection(std::move(connection_socket)),
43
3038
      listener_filter_manager_(std::move(listener_filter_manager)) {
44
3038
#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
3038
  set_defer_send_in_response_to_packets(GetQuicFlag(quic_defer_send_in_response));
50
3038
#endif
51
3038
}
52

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

            
66
1
  return true;
67
241926
}
68

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

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

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

            
91
239414
  quic::QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
92
239414
};
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