Bug 1427675 - Add TlsAgent argument to TlsRecordFilter, r=ekr
authorMartin Thomson <martin.thomson@gmail.com>
Wed, 03 Jan 2018 15:36:18 +1100
changeset 14254 74e4cd34e49fa72806ed7405926591d90f4a2d2a
parent 14253 f47d5a4034111a25e7096f8d0ba42f19cdb1dd26
child 14255 54a2412cbcc3c1016fa3cd0cf1fbcb52cb116ebc
push id2995
push usermartin.thomson@gmail.com
push dateThu, 15 Feb 2018 01:47:05 +0000
reviewersekr
bugs1427675
Bug 1427675 - Add TlsAgent argument to TlsRecordFilter, r=ekr This is a fairly disruptive change, but mostly just mechanical. There are a few extra changes: - I have renamed the TlsInspector* filters for consistency. This was purely mechanical. - I renamed the SetPacketFilter function to just SetFilter. Also mechanical. - TlsRecordFilter maintains a weak pointer reference to the TlsAgent now rather than using a bare pointer. This meant that I had to change TlsAgentTestBase to use shared_ptr rather than unique_ptr to support of use of filters with those tests. - I removed the helper function that enables decryption. Enabling decryption is now more explicit. - I ran a newer clang-format version and it fixed a few extra things, like the comments on the end of namespace {} blocks, some of which were wrong. - I discovered a bug in some of the drop tests: in the 0-RTT tests, the filters were being installed on the client and server right at the start, which meant that they were capturing the first handshake and not the second one. This was clearly against intent, but the tests were mostly right still, it was only the expected ACKs that were wrong. We were expecting just one record to be ACKed by a server (Finished), but the record with EndOfEarlyData should have been acknowledged as well. - In TlsSkipTest and Tls13SkipTest, I had to override SetUp() so that client_ and server_ are initialized prior to constructing filters. In doing so, I noticed that we weren't being consistent about overriding SetUp properly, so I fixed the small number of instances of that by adding an override label to each and marking the base method virtual. - The stateless HRR test for TLS 1.3 compat mode was replacing the server, but expecting to retain the same filters. That wasn't a problem in that case, but I didn't want to have any places where the filter was set on a different agent from the one that was passed to it.
gtests/ssl_gtest/bloomfilter_unittest.cc
gtests/ssl_gtest/ssl_0rtt_unittest.cc
gtests/ssl_gtest/ssl_agent_unittest.cc
gtests/ssl_gtest/ssl_auth_unittest.cc
gtests/ssl_gtest/ssl_cert_ext_unittest.cc
gtests/ssl_gtest/ssl_ciphersuite_unittest.cc
gtests/ssl_gtest/ssl_custext_unittest.cc
gtests/ssl_gtest/ssl_damage_unittest.cc
gtests/ssl_gtest/ssl_dhe_unittest.cc
gtests/ssl_gtest/ssl_drop_unittest.cc
gtests/ssl_gtest/ssl_ecdh_unittest.cc
gtests/ssl_gtest/ssl_extension_unittest.cc
gtests/ssl_gtest/ssl_fragment_unittest.cc
gtests/ssl_gtest/ssl_fuzz_unittest.cc
gtests/ssl_gtest/ssl_hrr_unittest.cc
gtests/ssl_gtest/ssl_keylog_unittest.cc
gtests/ssl_gtest/ssl_loopback_unittest.cc
gtests/ssl_gtest/ssl_record_unittest.cc
gtests/ssl_gtest/ssl_resumption_unittest.cc
gtests/ssl_gtest/ssl_skip_unittest.cc
gtests/ssl_gtest/ssl_staticrsa_unittest.cc
gtests/ssl_gtest/ssl_tls13compat_unittest.cc
gtests/ssl_gtest/ssl_v2_client_hello_unittest.cc
gtests/ssl_gtest/ssl_version_unittest.cc
gtests/ssl_gtest/ssl_versionpolicy_unittest.cc
gtests/ssl_gtest/test_io.cc
gtests/ssl_gtest/test_io.h
gtests/ssl_gtest/tls_agent.h
gtests/ssl_gtest/tls_connect.cc
gtests/ssl_gtest/tls_connect.h
gtests/ssl_gtest/tls_filter.cc
gtests/ssl_gtest/tls_filter.h
--- a/gtests/ssl_gtest/bloomfilter_unittest.cc
+++ b/gtests/ssl_gtest/bloomfilter_unittest.cc
@@ -100,9 +100,9 @@ static const BloomFilterConfig kBloomFil
     {2, 18},   // A moderately large allocation.
     {16, 16},  // Insane, use all of the bits from the hashes.
     {16, 9},   // This also uses all of the bits from the hashes.
 };
 
 INSTANTIATE_TEST_CASE_P(BloomFilterConfigurations, BloomFilterTest,
                         ::testing::ValuesIn(kBloomFilterConfigurations));
 
-}  // namespace nspr_test
+}  // namespace nss_test
--- a/gtests/ssl_gtest/ssl_0rtt_unittest.cc
+++ b/gtests/ssl_gtest/ssl_0rtt_unittest.cc
@@ -89,17 +89,17 @@ class TlsZeroRttReplayTest : public TlsC
 
  protected:
   void RunTest(bool rollover) {
     // Run the initial handshake
     SetupForZeroRtt();
 
     // Now run a true 0-RTT handshake, but capture the first packet.
     auto first_packet = std::make_shared<SaveFirstPacket>();
-    client_->SetPacketFilter(first_packet);
+    client_->SetFilter(first_packet);
     client_->Set0RttEnabled(true);
     server_->Set0RttEnabled(true);
     ExpectResumption(RESUME_TICKET);
     ZeroRttSendReceive(true, true);
     Handshake();
     EXPECT_LT(0U, first_packet->packet().len());
     ExpectEarlyDataAccepted(true);
     CheckConnected();
@@ -110,19 +110,19 @@ class TlsZeroRttReplayTest : public TlsC
     }
 
     // Now replay that packet against the server.
     Reset();
     server_->StartConnect();
     server_->Set0RttEnabled(true);
 
     // Capture the early_data extension, which should not appear.
-    auto early_data_ext =
-        std::make_shared<TlsExtensionCapture>(ssl_tls13_early_data_xtn);
-    server_->SetPacketFilter(early_data_ext);
+    auto early_data_ext = std::make_shared<TlsExtensionCapture>(
+        server_, ssl_tls13_early_data_xtn);
+    server_->SetFilter(early_data_ext);
 
     // Finally, replay the ClientHello and force the server to consume it.  Stop
     // after the server sends its first flight; the client will not be able to
     // complete this handshake.
     server_->adapter()->PacketReceived(first_packet->packet());
     server_->Handshake();
     EXPECT_FALSE(early_data_ext->captured());
   }
@@ -602,17 +602,17 @@ TEST_P(TlsConnectTls13, ZeroRttOrdering)
   ExpectResumption(RESUME_TICKET);
 
   // Send out the ClientHello.
   client_->Handshake();
 
   // Now, coalesce the next three things from the client: early data, second
   // flight and 1-RTT data.
   auto coalesce = std::make_shared<PacketCoalesceFilter>();
-  client_->SetPacketFilter(coalesce);
+  client_->SetFilter(coalesce);
 
   // Send (and hold) early data.
   static const std::vector<uint8_t> early_data = {3, 2, 1};
   EXPECT_EQ(static_cast<PRInt32>(early_data.size()),
             PR_Write(client_->ssl_fd(), early_data.data(), early_data.size()));
 
   // Send (and hold) the second client handshake flight.
   // The client sends EndOfEarlyData after seeing the server Finished.
--- a/gtests/ssl_gtest/ssl_agent_unittest.cc
+++ b/gtests/ssl_gtest/ssl_agent_unittest.cc
@@ -155,19 +155,19 @@ TEST_F(TlsAgentDgramTestClient, Encrypte
 }
 
 TEST_F(TlsAgentStreamTestClient, Set0RttOptionThenWrite) {
   EnsureInit();
   agent_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                           SSL_LIBRARY_VERSION_TLS_1_3);
   agent_->StartConnect();
   agent_->Set0RttEnabled(true);
-  auto filter = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      kTlsHandshakeClientHello);
-  agent_->SetPacketFilter(filter);
+  auto filter =
+      std::make_shared<TlsHandshakeRecorder>(agent_, kTlsHandshakeClientHello);
+  agent_->SetFilter(filter);
   PRInt32 rv = PR_Write(agent_->ssl_fd(), k0RttData, strlen(k0RttData));
   EXPECT_EQ(-1, rv);
   int32_t err = PORT_GetError();
   EXPECT_EQ(PR_WOULD_BLOCK_ERROR, err);
   EXPECT_LT(0UL, filter->buffer().len());
 }
 
 TEST_F(TlsAgentStreamTestClient, Set0RttOptionThenRead) {
--- a/gtests/ssl_gtest/ssl_auth_unittest.cc
+++ b/gtests/ssl_gtest/ssl_auth_unittest.cc
@@ -90,84 +90,81 @@ TEST_P(TlsConnectGeneric, ClientAuthBigR
   Reset(TlsAgent::kServerRsa, TlsAgent::kRsa2048);
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   Connect();
   CheckKeys();
 }
 
 // Offset is the position in the captured buffer where the signature sits.
-static void CheckSigScheme(
-    std::shared_ptr<TlsInspectorRecordHandshakeMessage>& capture, size_t offset,
-    std::shared_ptr<TlsAgent>& peer, uint16_t expected_scheme,
-    size_t expected_size) {
+static void CheckSigScheme(std::shared_ptr<TlsHandshakeRecorder>& capture,
+                           size_t offset, std::shared_ptr<TlsAgent>& peer,
+                           uint16_t expected_scheme, size_t expected_size) {
   EXPECT_LT(offset + 2U, capture->buffer().len());
 
   uint32_t scheme = 0;
   capture->buffer().Read(offset, 2, &scheme);
   EXPECT_EQ(expected_scheme, static_cast<uint16_t>(scheme));
 
   ScopedCERTCertificate remote_cert(SSL_PeerCertificate(peer->ssl_fd()));
   ScopedSECKEYPublicKey remote_key(CERT_ExtractPublicKey(remote_cert.get()));
   EXPECT_EQ(expected_size, SECKEY_PublicKeyStrengthInBits(remote_key.get()));
 }
 
 // The server should prefer SHA-256 by default, even for the small key size used
 // in the default certificate.
 TEST_P(TlsConnectTls12, ServerAuthCheckSigAlg) {
   EnsureTlsSetup();
-  auto capture_ske = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      kTlsHandshakeServerKeyExchange);
-  server_->SetPacketFilter(capture_ske);
+  auto capture_ske = std::make_shared<TlsHandshakeRecorder>(
+      server_, kTlsHandshakeServerKeyExchange);
+  server_->SetFilter(capture_ske);
   Connect();
   CheckKeys();
 
   const DataBuffer& buffer = capture_ske->buffer();
   EXPECT_LT(3U, buffer.len());
   EXPECT_EQ(3U, buffer.data()[0]) << "curve_type == named_curve";
   uint32_t tmp;
   EXPECT_TRUE(buffer.Read(1, 2, &tmp)) << "read NamedCurve";
   EXPECT_EQ(ssl_grp_ec_curve25519, tmp);
   EXPECT_TRUE(buffer.Read(3, 1, &tmp)) << " read ECPoint";
   CheckSigScheme(capture_ske, 4 + tmp, client_, ssl_sig_rsa_pss_rsae_sha256,
                  1024);
 }
 
 TEST_P(TlsConnectTls12, ClientAuthCheckSigAlg) {
   EnsureTlsSetup();
-  auto capture_cert_verify =
-      std::make_shared<TlsInspectorRecordHandshakeMessage>(
-          kTlsHandshakeCertificateVerify);
-  client_->SetPacketFilter(capture_cert_verify);
+  auto capture_cert_verify = std::make_shared<TlsHandshakeRecorder>(
+      client_, kTlsHandshakeCertificateVerify);
+  client_->SetFilter(capture_cert_verify);
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   Connect();
   CheckKeys();
 
   CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pkcs1_sha1, 1024);
 }
 
 TEST_P(TlsConnectTls12, ClientAuthBigRsaCheckSigAlg) {
   Reset(TlsAgent::kServerRsa, TlsAgent::kRsa2048);
-  auto capture_cert_verify =
-      std::make_shared<TlsInspectorRecordHandshakeMessage>(
-          kTlsHandshakeCertificateVerify);
-  client_->SetPacketFilter(capture_cert_verify);
+  auto capture_cert_verify = std::make_shared<TlsHandshakeRecorder>(
+      client_, kTlsHandshakeCertificateVerify);
+  client_->SetFilter(capture_cert_verify);
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   Connect();
   CheckKeys();
   CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pss_rsae_sha256,
                  2048);
 }
 
 class TlsZeroCertificateRequestSigAlgsFilter : public TlsHandshakeFilter {
  public:
-  TlsZeroCertificateRequestSigAlgsFilter()
-      : TlsHandshakeFilter({kTlsHandshakeCertificateRequest}) {}
+  TlsZeroCertificateRequestSigAlgsFilter(const std::shared_ptr<TlsAgent>& agent)
+      : TlsHandshakeFilter(agent, {kTlsHandshakeCertificateRequest}) {}
   virtual PacketFilter::Action FilterHandshake(
       const TlsHandshakeFilter::HandshakeHeader& header,
       const DataBuffer& input, DataBuffer* output) {
     TlsParser parser(input);
     std::cerr << "Zeroing CertReq.supported_signature_algorithms" << std::endl;
 
     DataBuffer cert_types;
     if (!parser.ReadVariable(&cert_types, 1)) {
@@ -202,22 +199,22 @@ class TlsZeroCertificateRequestSigAlgsFi
     return CHANGE;
   }
 };
 
 // Check that we fall back to SHA-1 when the server doesn't provide any
 // supported_signature_algorithms in the CertificateRequest message.
 TEST_P(TlsConnectTls12, ClientAuthNoSigAlgsFallback) {
   EnsureTlsSetup();
-  auto filter = std::make_shared<TlsZeroCertificateRequestSigAlgsFilter>();
-  server_->SetPacketFilter(filter);
-  auto capture_cert_verify =
-      std::make_shared<TlsInspectorRecordHandshakeMessage>(
-          kTlsHandshakeCertificateVerify);
-  client_->SetPacketFilter(capture_cert_verify);
+  auto filter =
+      std::make_shared<TlsZeroCertificateRequestSigAlgsFilter>(server_);
+  server_->SetFilter(filter);
+  auto capture_cert_verify = std::make_shared<TlsHandshakeRecorder>(
+      client_, kTlsHandshakeCertificateVerify);
+  client_->SetFilter(capture_cert_verify);
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
 
   ConnectExpectAlert(server_, kTlsAlertDecryptError);
 
   // We're expecting a bad signature here because we tampered with a handshake
   // message (CertReq). Previously, without the SHA-1 fallback, we would've
   // seen a malformed record alert.
@@ -355,28 +352,28 @@ TEST_P(TlsConnectPre12, SignatureAlgorit
                                PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
   server_->SetSignatureSchemes(SignatureSchemeEcdsaSha256,
                                PR_ARRAY_SIZE(SignatureSchemeEcdsaSha256));
   Connect();
 }
 
 // The signature_algorithms extension is mandatory in TLS 1.3.
 TEST_P(TlsConnectTls13, SignatureAlgorithmDrop) {
-  client_->SetPacketFilter(
-      std::make_shared<TlsExtensionDropper>(ssl_signature_algorithms_xtn));
+  client_->SetFilter(std::make_shared<TlsExtensionDropper>(
+      client_, ssl_signature_algorithms_xtn));
   ConnectExpectAlert(server_, kTlsAlertMissingExtension);
   client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT);
   server_->CheckErrorCode(SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION);
 }
 
 // TLS 1.2 has trouble detecting this sort of modification: it uses SHA1 and
 // only fails when the Finished is checked.
 TEST_P(TlsConnectTls12, SignatureAlgorithmDrop) {
-  client_->SetPacketFilter(
-      std::make_shared<TlsExtensionDropper>(ssl_signature_algorithms_xtn));
+  client_->SetFilter(std::make_shared<TlsExtensionDropper>(
+      client_, ssl_signature_algorithms_xtn));
   ConnectExpectAlert(server_, kTlsAlertDecryptError);
   client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
   server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
 }
 
 TEST_P(TlsConnectTls12Plus, RequestClientAuthWithSha384) {
   server_->SetSignatureSchemes(SignatureSchemeRsaSha384,
                                PR_ARRAY_SIZE(SignatureSchemeRsaSha384));
@@ -384,21 +381,21 @@ TEST_P(TlsConnectTls12Plus, RequestClien
   Connect();
 }
 
 class BeforeFinished : public TlsRecordFilter {
  private:
   enum HandshakeState { BEFORE_CCS, AFTER_CCS, DONE };
 
  public:
-  BeforeFinished(std::shared_ptr<TlsAgent>& client,
-                 std::shared_ptr<TlsAgent>& server, VoidFunction before_ccs,
-                 VoidFunction before_finished)
-      : client_(client),
-        server_(server),
+  BeforeFinished(const std::shared_ptr<TlsAgent>& client,
+                 const std::shared_ptr<TlsAgent>& server,
+                 VoidFunction before_ccs, VoidFunction before_finished)
+      : TlsRecordFilter(server),
+        client_(client),
         before_ccs_(before_ccs),
         before_finished_(before_finished),
         state_(BEFORE_CCS) {}
 
  protected:
   virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                             const DataBuffer& body,
                                             DataBuffer* out) {
@@ -408,17 +405,17 @@ class BeforeFinished : public TlsRecordF
         if (header.content_type() == kTlsChangeCipherSpecType) {
           before_ccs_();
 
           // Write the CCS out as a separate write, so that we can make
           // progress. Ordinarily, libssl sends the CCS and Finished together,
           // but that means that they both get processed together.
           DataBuffer ccs;
           header.Write(&ccs, 0, body);
-          server_.lock()->SendDirect(ccs);
+          agent()->SendDirect(ccs);
           client_.lock()->Handshake();
           state_ = AFTER_CCS;
           // Request that the original record be dropped by the filter.
           return DROP;
         }
         break;
 
       case AFTER_CCS:
@@ -433,17 +430,16 @@ class BeforeFinished : public TlsRecordF
       case DONE:
         break;
     }
     return KEEP;
   }
 
  private:
   std::weak_ptr<TlsAgent> client_;
-  std::weak_ptr<TlsAgent> server_;
   VoidFunction before_ccs_;
   VoidFunction before_finished_;
   HandshakeState state_;
 };
 
 // Running code after the client has started processing the encrypted part of
 // the server's first flight, but before the Finished is processed is very hard
 // in TLS 1.3.  These encrypted messages are sent in a single encrypted blob.
@@ -458,18 +454,18 @@ class BeforeFinished13 : public PacketFi
   enum HandshakeState {
     INIT,
     BEFORE_FIRST_FRAGMENT,
     BEFORE_SECOND_FRAGMENT,
     DONE
   };
 
  public:
-  BeforeFinished13(std::shared_ptr<TlsAgent>& client,
-                   std::shared_ptr<TlsAgent>& server,
+  BeforeFinished13(const std::shared_ptr<TlsAgent>& client,
+                   const std::shared_ptr<TlsAgent>& server,
                    VoidFunction before_finished)
       : client_(client),
         server_(server),
         before_finished_(before_finished),
         records_(0) {}
 
  protected:
   virtual PacketFilter::Action Filter(const DataBuffer& input,
@@ -509,17 +505,17 @@ static SECStatus AuthCompleteBlock(TlsAg
   return SECWouldBlock;
 }
 
 // This test uses an AuthCertificateCallback that blocks.  A filter is used to
 // split the server's first flight into two pieces.  Before the second piece is
 // processed by the client, SSL_AuthCertificateComplete() is called.
 TEST_F(TlsConnectDatagram13, AuthCompleteBeforeFinished) {
   client_->SetAuthCertificateCallback(AuthCompleteBlock);
-  server_->SetPacketFilter(
+  server_->SetFilter(
       std::make_shared<BeforeFinished13>(client_, server_, [this]() {
         EXPECT_EQ(SECSuccess,
                   SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
       }));
   Connect();
 }
 
 static void TriggerAuthComplete(PollTarget* target, Event event) {
@@ -541,33 +537,33 @@ TEST_F(TlsConnectDatagram13, AuthComplet
                                      &timer_handle);
         return SECWouldBlock;
       });
   Connect();
 }
 
 TEST_P(TlsConnectGenericPre13, ClientWriteBetweenCCSAndFinishedWithFalseStart) {
   client_->EnableFalseStart();
-  server_->SetPacketFilter(std::make_shared<BeforeFinished>(
+  server_->SetFilter(std::make_shared<BeforeFinished>(
       client_, server_,
       [this]() { EXPECT_TRUE(client_->can_falsestart_hook_called()); },
       [this]() {
         // Write something, which used to fail: bug 1235366.
         client_->SendData(10);
       }));
 
   Connect();
   server_->SendData(10);
   Receive(10);
 }
 
 TEST_P(TlsConnectGenericPre13, AuthCompleteBeforeFinishedWithFalseStart) {
   client_->EnableFalseStart();
   client_->SetAuthCertificateCallback(AuthCompleteBlock);
-  server_->SetPacketFilter(std::make_shared<BeforeFinished>(
+  server_->SetFilter(std::make_shared<BeforeFinished>(
       client_, server_,
       []() {
         // Do nothing before CCS
       },
       [this]() {
         EXPECT_FALSE(client_->can_falsestart_hook_called());
         // AuthComplete before Finished still enables false start.
         EXPECT_EQ(SECSuccess,
@@ -603,48 +599,48 @@ TEST_P(TlsConnectGenericPre13, AuthCompl
   client_->Handshake();  // Send ClientHello
   server_->Handshake();  // Send ServerHello
   client_->Handshake();  // Send ClientKeyExchange and Finished
   server_->Handshake();  // Send Finished
   // The server should now report that it is connected
   EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
 
   // The client should send nothing from here on.
-  client_->SetPacketFilter(std::make_shared<EnforceNoActivity>());
+  client_->SetFilter(std::make_shared<EnforceNoActivity>());
   client_->Handshake();
   EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
 
   // This should allow the handshake to complete now.
   EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
   client_->Handshake();  // Transition to connected
   EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
   EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
 
-  // Remove this before closing or the close_notify alert will trigger it.
-  client_->DeletePacketFilter();
+  // Remove filter before closing or the close_notify alert will trigger it.
+  client_->ClearFilter();
 }
 
 TEST_P(TlsConnectGenericPre13, AuthCompleteFailDelayed) {
   client_->SetAuthCertificateCallback(AuthCompleteBlock);
 
   StartConnect();
   client_->Handshake();  // Send ClientHello
   server_->Handshake();  // Send ServerHello
   client_->Handshake();  // Send ClientKeyExchange and Finished
   server_->Handshake();  // Send Finished
   // The server should now report that it is connected
   EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
 
   // The client should send nothing from here on.
-  client_->SetPacketFilter(std::make_shared<EnforceNoActivity>());
+  client_->SetFilter(std::make_shared<EnforceNoActivity>());
   client_->Handshake();
   EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
 
   // Report failure.
-  client_->DeletePacketFilter();
+  client_->ClearFilter();
   client_->ExpectSendAlert(kTlsAlertBadCertificate);
   EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(),
                                                     SSL_ERROR_BAD_CERTIFICATE));
   client_->Handshake();  // Fail
   EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
 }
 
 // TLS 1.3 handles a delayed AuthComplete callback differently since the
@@ -654,22 +650,22 @@ TEST_P(TlsConnectTls13, AuthCompleteDela
 
   StartConnect();
   client_->Handshake();  // Send ClientHello
   server_->Handshake();  // Send ServerHello
   EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
   EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state());
 
   // The client will send nothing until AuthCertificateComplete is called.
-  client_->SetPacketFilter(std::make_shared<EnforceNoActivity>());
+  client_->SetFilter(std::make_shared<EnforceNoActivity>());
   client_->Handshake();
   EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
 
   // This should allow the handshake to complete now.
-  client_->DeletePacketFilter();
+  client_->ClearFilter();
   EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
   client_->Handshake();  // Send Finished
   server_->Handshake();  // Transition to connected and send NewSessionTicket
   EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
   EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
 }
 
 TEST_P(TlsConnectTls13, AuthCompleteFailDelayed) {
@@ -677,22 +673,22 @@ TEST_P(TlsConnectTls13, AuthCompleteFail
 
   StartConnect();
   client_->Handshake();  // Send ClientHello
   server_->Handshake();  // Send ServerHello
   EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
   EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state());
 
   // The client will send nothing until AuthCertificateComplete is called.
-  client_->SetPacketFilter(std::make_shared<EnforceNoActivity>());
+  client_->SetFilter(std::make_shared<EnforceNoActivity>());
   client_->Handshake();
   EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
 
   // Report failure.
-  client_->DeletePacketFilter();
+  client_->ClearFilter();
   ExpectAlert(client_, kTlsAlertBadCertificate);
   EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(),
                                                     SSL_ERROR_BAD_CERTIFICATE));
   client_->Handshake();  // This should now fail.
   server_->Handshake();  // Get the error.
   EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
   EXPECT_EQ(TlsAgent::STATE_ERROR, server_->state());
 }
@@ -826,19 +822,19 @@ class TlsSignatureSchemeConfiguration
 
 TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigServer) {
   Reset(certificate_);
   TestSignatureSchemeConfig(server_);
 }
 
 TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigClient) {
   Reset(certificate_);
-  auto capture =
-      std::make_shared<TlsExtensionCapture>(ssl_signature_algorithms_xtn);
-  client_->SetPacketFilter(capture);
+  auto capture = std::make_shared<TlsExtensionCapture>(
+      client_, ssl_signature_algorithms_xtn);
+  client_->SetFilter(capture);
   TestSignatureSchemeConfig(client_);
 
   const DataBuffer& ext = capture->extension();
   ASSERT_EQ(2U + 2U, ext.len());
   uint32_t v = 0;
   ASSERT_TRUE(ext.Read(0, 2, &v));
   EXPECT_EQ(2U, v);
   ASSERT_TRUE(ext.Read(2, 2, &v));
@@ -902,9 +898,9 @@ INSTANTIATE_TEST_CASE_P(
 INSTANTIATE_TEST_CASE_P(
     SignatureSchemeEcdsaSha1, TlsSignatureSchemeConfiguration,
     ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
                        TlsConnectTestBase::kTlsV12,
                        ::testing::Values(TlsAgent::kServerEcdsa256,
                                          TlsAgent::kServerEcdsa384),
                        ::testing::Values(ssl_auth_ecdsa),
                        ::testing::Values(ssl_sig_ecdsa_sha1)));
-}
+}  // namespace nss_test
--- a/gtests/ssl_gtest/ssl_cert_ext_unittest.cc
+++ b/gtests/ssl_gtest/ssl_cert_ext_unittest.cc
@@ -176,29 +176,29 @@ TEST_P(TlsConnectGeneric, OcspNotProvide
 TEST_P(TlsConnectGenericPre13, OcspMangled) {
   EnsureTlsSetup();
   client_->SetOption(SSL_ENABLE_OCSP_STAPLING, PR_TRUE);
   EXPECT_TRUE(
       server_->ConfigServerCert(TlsAgent::kServerRsa, true, &kOcspExtraData));
 
   static const uint8_t val[] = {1};
   auto replacer = std::make_shared<TlsExtensionReplacer>(
-      ssl_cert_status_xtn, DataBuffer(val, sizeof(val)));
-  server_->SetPacketFilter(replacer);
+      server_, ssl_cert_status_xtn, DataBuffer(val, sizeof(val)));
+  server_->SetFilter(replacer);
   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
   client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
 }
 
 TEST_P(TlsConnectGeneric, OcspSuccess) {
   EnsureTlsSetup();
   client_->SetOption(SSL_ENABLE_OCSP_STAPLING, PR_TRUE);
   auto capture_ocsp =
-      std::make_shared<TlsExtensionCapture>(ssl_cert_status_xtn);
-  server_->SetPacketFilter(capture_ocsp);
+      std::make_shared<TlsExtensionCapture>(server_, ssl_cert_status_xtn);
+  server_->SetFilter(capture_ocsp);
 
   // The value should be available during the AuthCertificateCallback
   client_->SetAuthCertificateCallback([](TlsAgent* agent, bool checksig,
                                          bool isServer) -> SECStatus {
     const SECItemArray* ocsp = SSL_PeerStapledOCSPResponses(agent->ssl_fd());
     if (!ocsp) {
       return SECFailure;
     }
@@ -240,9 +240,9 @@ TEST_P(TlsConnectGeneric, OcspHugeSucces
     return SECSuccess;
   });
   EXPECT_TRUE(server_->ConfigServerCert(TlsAgent::kServerRsa, true,
                                         &hugeOcspExtraData));
 
   Connect();
 }
 
-}  // namespace nspr_test
+}  // namespace nss_test
--- a/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc
+++ b/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc
@@ -461,9 +461,9 @@ static const SecStatusParams kSecStatusT
      "AES-128-GCM", 128},
     {SSL_LIBRARY_VERSION_TLS_1_2, TLS_RSA_WITH_AES_256_GCM_SHA384,
      "AES-256-GCM", 256},
     {SSL_LIBRARY_VERSION_TLS_1_2, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
      "ChaCha20-Poly1305", 256}};
 INSTANTIATE_TEST_CASE_P(TestSecurityStatus, SecurityStatusTest,
                         ::testing::ValuesIn(kSecStatusTestValuesArr));
 
-}  // namespace nspr_test
+}  // namespace nss_test
--- a/gtests/ssl_gtest/ssl_custext_unittest.cc
+++ b/gtests/ssl_gtest/ssl_custext_unittest.cc
@@ -145,19 +145,19 @@ TEST_F(TlsConnectStreamTls13, CustomExte
   EXPECT_EQ(SECSuccess, rv);
 
   // This installs an override that doesn't do anything.  You have to specify
   // something; passing all nullptr values removes an existing handler.
   rv = SSL_InstallExtensionHooks(
       client_->ssl_fd(), ssl_signed_cert_timestamp_xtn, NoopExtensionWriter,
       nullptr, NoopExtensionHandler, nullptr);
   EXPECT_EQ(SECSuccess, rv);
-  auto capture =
-      std::make_shared<TlsExtensionCapture>(ssl_signed_cert_timestamp_xtn);
-  client_->SetPacketFilter(capture);
+  auto capture = std::make_shared<TlsExtensionCapture>(
+      client_, ssl_signed_cert_timestamp_xtn);
+  client_->SetFilter(capture);
 
   Connect();
   // So nothing will be sent.
   EXPECT_FALSE(capture->captured());
 }
 
 // An extension that is unlikely to be parsed as valid.
 static uint8_t kNonsenseExtension[] = {91, 82, 73, 64, 55, 46, 37, 28, 19};
@@ -199,19 +199,19 @@ TEST_F(TlsConnectStreamTls13, CustomExte
 
   // This installs an override that sends nonsense.
   rv = SSL_InstallExtensionHooks(
       client_->ssl_fd(), ssl_signed_cert_timestamp_xtn, NonsenseExtensionWriter,
       client_.get(), NoopExtensionHandler, nullptr);
   EXPECT_EQ(SECSuccess, rv);
 
   // Capture it to see what we got.
-  auto capture =
-      std::make_shared<TlsExtensionCapture>(ssl_signed_cert_timestamp_xtn);
-  client_->SetPacketFilter(capture);
+  auto capture = std::make_shared<TlsExtensionCapture>(
+      client_, ssl_signed_cert_timestamp_xtn);
+  client_->SetFilter(capture);
 
   ConnectExpectAlert(server_, kTlsAlertDecodeError);
 
   EXPECT_TRUE(capture->captured());
   EXPECT_EQ(DataBuffer(kNonsenseExtension, sizeof(kNonsenseExtension)),
             capture->extension());
 }
 
@@ -241,18 +241,18 @@ TEST_F(TlsConnectStreamTls13, CustomExte
   // This installs an override that sends nonsense.
   const uint16_t extension_code = 0xffe5;
   SECStatus rv = SSL_InstallExtensionHooks(
       client_->ssl_fd(), extension_code, NonsenseExtensionWriter, client_.get(),
       NoopExtensionHandler, nullptr);
   EXPECT_EQ(SECSuccess, rv);
 
   // Capture it to see what we got.
-  auto capture = std::make_shared<TlsExtensionCapture>(extension_code);
-  client_->SetPacketFilter(capture);
+  auto capture = std::make_shared<TlsExtensionCapture>(client_, extension_code);
+  client_->SetFilter(capture);
 
   // Handle it so that the handshake completes.
   rv = SSL_InstallExtensionHooks(server_->ssl_fd(), extension_code,
                                  NoopExtensionWriter, nullptr,
                                  NonsenseExtensionHandler, server_.get());
   EXPECT_EQ(SECSuccess, rv);
 
   Connect();
@@ -285,19 +285,19 @@ TEST_F(TlsConnectStreamTls13, CustomExte
 
   // Have the server send nonsense.
   rv = SSL_InstallExtensionHooks(server_->ssl_fd(), extension_code,
                                  NonsenseExtensionWriterSH, server_.get(),
                                  NoopExtensionHandler, nullptr);
   EXPECT_EQ(SECSuccess, rv);
 
   // Capture the extension from the ServerHello only and check it.
-  auto capture = std::make_shared<TlsExtensionCapture>(extension_code);
+  auto capture = std::make_shared<TlsExtensionCapture>(server_, extension_code);
   capture->SetHandshakeTypes({kTlsHandshakeServerHello});
-  server_->SetPacketFilter(capture);
+  server_->SetFilter(capture);
 
   Connect();
 
   EXPECT_TRUE(capture->captured());
   EXPECT_EQ(DataBuffer(kNonsenseExtension, sizeof(kNonsenseExtension)),
             capture->extension());
 }
 
@@ -324,19 +324,20 @@ TEST_F(TlsConnectStreamTls13, CustomExte
 
   // Have the server send nonsense.
   rv = SSL_InstallExtensionHooks(server_->ssl_fd(), extension_code,
                                  NonsenseExtensionWriterEE, server_.get(),
                                  NoopExtensionHandler, nullptr);
   EXPECT_EQ(SECSuccess, rv);
 
   // Capture the extension from the EncryptedExtensions only and check it.
-  auto capture = std::make_shared<TlsExtensionCapture>(extension_code);
+  auto capture = std::make_shared<TlsExtensionCapture>(server_, extension_code);
   capture->SetHandshakeTypes({kTlsHandshakeEncryptedExtensions});
-  server_->SetTlsRecordFilter(capture);
+  capture->EnableDecryption();
+  server_->SetFilter(capture);
 
   Connect();
 
   EXPECT_TRUE(capture->captured());
   EXPECT_EQ(DataBuffer(kNonsenseExtension, sizeof(kNonsenseExtension)),
             capture->extension());
 }
 
@@ -345,18 +346,18 @@ TEST_F(TlsConnectStreamTls13, CustomExte
 
   const uint16_t extension_code = 0xff5e;
   SECStatus rv = SSL_InstallExtensionHooks(
       server_->ssl_fd(), extension_code, NonsenseExtensionWriter, server_.get(),
       NoopExtensionHandler, nullptr);
   EXPECT_EQ(SECSuccess, rv);
 
   // Capture it to see what we got.
-  auto capture = std::make_shared<TlsExtensionCapture>(extension_code);
-  server_->SetPacketFilter(capture);
+  auto capture = std::make_shared<TlsExtensionCapture>(server_, extension_code);
+  server_->SetFilter(capture);
 
   client_->ExpectSendAlert(kTlsAlertUnsupportedExtension);
   server_->ExpectSendAlert(kTlsAlertBadRecordMac);
   ConnectExpectFail();
 
   EXPECT_TRUE(capture->captured());
   EXPECT_EQ(DataBuffer(kNonsenseExtension, sizeof(kNonsenseExtension)),
             capture->extension());
@@ -495,9 +496,9 @@ TEST_F(TlsConnectStreamTls13, CustomExte
       SSL_InstallExtensionHooks(client_->ssl_fd(), 0xff71, overrun_writer,
                                 nullptr, NoopExtensionHandler, nullptr);
   EXPECT_EQ(SECSuccess, rv);
   client_->StartConnect();
   client_->Handshake();
   client_->CheckErrorCode(SEC_ERROR_APPLICATION_CALLBACK_ERROR);
 }
 
-}  // namespace "nss_test"
+}  // namespace nss_test
--- a/gtests/ssl_gtest/ssl_damage_unittest.cc
+++ b/gtests/ssl_gtest/ssl_damage_unittest.cc
@@ -45,59 +45,62 @@ TEST_F(TlsConnectTest, DamageSecretHandl
   client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
 }
 
 TEST_F(TlsConnectTest, DamageSecretHandleServerFinished) {
   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
                            SSL_LIBRARY_VERSION_TLS_1_3);
-  server_->SetPacketFilter(std::make_shared<AfterRecordN>(
+  server_->SetFilter(std::make_shared<AfterRecordN>(
       server_, client_,
       0,  // ServerHello.
       [this]() { SSLInt_DamageServerHsTrafficSecret(client_->ssl_fd()); }));
   ConnectExpectAlert(client_, kTlsAlertDecryptError);
   client_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
 }
 
 TEST_P(TlsConnectGenericPre13, DamageServerSignature) {
   EnsureTlsSetup();
-  auto filter =
-      std::make_shared<TlsLastByteDamager>(kTlsHandshakeServerKeyExchange);
-  server_->SetTlsRecordFilter(filter);
+  auto filter = std::make_shared<TlsLastByteDamager>(
+      server_, kTlsHandshakeServerKeyExchange);
+  filter->EnableDecryption();
+  server_->SetFilter(filter);
   ExpectAlert(client_, kTlsAlertDecryptError);
   ConnectExpectFail();
   client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
   server_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
 }
 
 TEST_P(TlsConnectTls13, DamageServerSignature) {
   EnsureTlsSetup();
-  auto filter =
-      std::make_shared<TlsLastByteDamager>(kTlsHandshakeCertificateVerify);
-  server_->SetTlsRecordFilter(filter);
+  auto filter = std::make_shared<TlsLastByteDamager>(
+      server_, kTlsHandshakeCertificateVerify);
+  filter->EnableDecryption();
+  server_->SetFilter(filter);
   ConnectExpectAlert(client_, kTlsAlertDecryptError);
   client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
 }
 
 TEST_P(TlsConnectGeneric, DamageClientSignature) {
   EnsureTlsSetup();
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
-  auto filter =
-      std::make_shared<TlsLastByteDamager>(kTlsHandshakeCertificateVerify);
-  client_->SetTlsRecordFilter(filter);
+  auto filter = std::make_shared<TlsLastByteDamager>(
+      client_, kTlsHandshakeCertificateVerify);
+  filter->EnableDecryption();
+  client_->SetFilter(filter);
   server_->ExpectSendAlert(kTlsAlertDecryptError);
   // Do these handshakes by hand to avoid race condition on
   // the client processing the server's alert.
   StartConnect();
   client_->Handshake();
   server_->Handshake();
   client_->Handshake();
   server_->Handshake();
   EXPECT_EQ(version_ >= SSL_LIBRARY_VERSION_TLS_1_3
                 ? TlsAgent::STATE_CONNECTED
                 : TlsAgent::STATE_CONNECTING,
             client_->state());
   server_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
 }
 
-}  // namespace nspr_test
+}  // namespace nss_test
--- a/gtests/ssl_gtest/ssl_dhe_unittest.cc
+++ b/gtests/ssl_gtest/ssl_dhe_unittest.cc
@@ -27,22 +27,22 @@ TEST_P(TlsConnectGeneric, ConnectDhe) {
             ssl_sig_rsa_pss_rsae_sha256);
 }
 
 TEST_P(TlsConnectTls13, SharesForBothEcdheAndDhe) {
   EnsureTlsSetup();
   client_->ConfigNamedGroups(kAllDHEGroups);
 
   auto groups_capture =
-      std::make_shared<TlsExtensionCapture>(ssl_supported_groups_xtn);
+      std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn);
   auto shares_capture =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
+      std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
   std::vector<std::shared_ptr<PacketFilter>> captures = {groups_capture,
                                                          shares_capture};
-  client_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(captures));
+  client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures));
 
   Connect();
 
   CheckKeys();
 
   bool ec, dh;
   auto track_group_type = [&ec, &dh](SSLNamedGroup group) {
     if ((group & 0xff00U) == 0x100U) {
@@ -56,22 +56,22 @@ TEST_P(TlsConnectTls13, SharesForBothEcd
   EXPECT_TRUE(ec) << "Should include an EC group and share";
   EXPECT_TRUE(dh) << "Should include an FFDHE group and share";
 }
 
 TEST_P(TlsConnectGeneric, ConnectFfdheClient) {
   EnableOnlyDheCiphers();
   client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
   auto groups_capture =
-      std::make_shared<TlsExtensionCapture>(ssl_supported_groups_xtn);
+      std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn);
   auto shares_capture =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
+      std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
   std::vector<std::shared_ptr<PacketFilter>> captures = {groups_capture,
                                                          shares_capture};
-  client_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(captures));
+  client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures));
 
   Connect();
 
   CheckKeys(ssl_kea_dh, ssl_auth_rsa_sign);
   auto is_ffdhe = [](SSLNamedGroup group) {
     // The group has to be in this range.
     EXPECT_LE(ssl_grp_ffdhe_2048, group);
     EXPECT_GE(ssl_grp_ffdhe_8192, group);
@@ -98,18 +98,18 @@ TEST_P(TlsConnectGenericPre13, ConnectFf
     ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
     client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
     server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
   }
 }
 
 class TlsDheServerKeyExchangeDamager : public TlsHandshakeFilter {
  public:
-  TlsDheServerKeyExchangeDamager()
-      : TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}) {}
+  TlsDheServerKeyExchangeDamager(const std::shared_ptr<TlsAgent>& agent)
+      : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {}
   virtual PacketFilter::Action FilterHandshake(
       const TlsHandshakeFilter::HandshakeHeader& header,
       const DataBuffer& input, DataBuffer* output) {
     // Damage the first octet of dh_p.  Anything other than the known prime will
     // be rejected as "weak" when we have SSL_REQUIRE_DH_NAMED_GROUPS enabled.
     *output = input;
     output->data()[3] ^= 73;
     return CHANGE;
@@ -117,17 +117,17 @@ class TlsDheServerKeyExchangeDamager : p
 };
 
 // Changing the prime in the server's key share results in an error.  This will
 // invalidate the signature over the ServerKeyShare. That's ok, NSS won't check
 // the signature until everything else has been checked.
 TEST_P(TlsConnectGenericPre13, DamageServerKeyShare) {
   EnableOnlyDheCiphers();
   client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
-  server_->SetPacketFilter(std::make_shared<TlsDheServerKeyExchangeDamager>());
+  server_->SetFilter(std::make_shared<TlsDheServerKeyExchangeDamager>(server_));
 
   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
 
   client_->CheckErrorCode(SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY);
   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
 }
 
 class TlsDheSkeChangeY : public TlsHandshakeFilter {
@@ -136,18 +136,19 @@ class TlsDheSkeChangeY : public TlsHands
     kYZero,
     kYOne,
     kYPMinusOne,
     kYGreaterThanP,
     kYTooLarge,
     kYZeroPad
   };
 
-  TlsDheSkeChangeY(uint8_t handshake_type, ChangeYTo change)
-      : TlsHandshakeFilter({handshake_type}), change_Y_(change) {}
+  TlsDheSkeChangeY(const std::shared_ptr<TlsAgent>& agent,
+                   uint8_t handshake_type, ChangeYTo change)
+      : TlsHandshakeFilter(agent, {handshake_type}), change_Y_(change) {}
 
  protected:
   void ChangeY(const DataBuffer& input, DataBuffer* output, size_t offset,
                const DataBuffer& prime) {
     static const uint8_t kExtraZero = 0;
     static const uint8_t kTooLargeExtra = 1;
 
     uint32_t dh_Ys_len;
@@ -202,18 +203,19 @@ class TlsDheSkeChangeY : public TlsHands
   }
 
  private:
   ChangeYTo change_Y_;
 };
 
 class TlsDheSkeChangeYServer : public TlsDheSkeChangeY {
  public:
-  TlsDheSkeChangeYServer(ChangeYTo change, bool modify)
-      : TlsDheSkeChangeY(kTlsHandshakeServerKeyExchange, change),
+  TlsDheSkeChangeYServer(const std::shared_ptr<TlsAgent>& agent,
+                         ChangeYTo change, bool modify)
+      : TlsDheSkeChangeY(agent, kTlsHandshakeServerKeyExchange, change),
         modify_(modify),
         p_() {}
 
   const DataBuffer& prime() const { return p_; }
 
  protected:
   virtual PacketFilter::Action FilterHandshake(
       const TlsHandshakeFilter::HandshakeHeader& header,
@@ -240,19 +242,19 @@ class TlsDheSkeChangeYServer : public Tl
  private:
   bool modify_;
   DataBuffer p_;
 };
 
 class TlsDheSkeChangeYClient : public TlsDheSkeChangeY {
  public:
   TlsDheSkeChangeYClient(
-      ChangeYTo change,
+      const std::shared_ptr<TlsAgent>& agent, ChangeYTo change,
       std::shared_ptr<const TlsDheSkeChangeYServer> server_filter)
-      : TlsDheSkeChangeY(kTlsHandshakeClientKeyExchange, change),
+      : TlsDheSkeChangeY(agent, kTlsHandshakeClientKeyExchange, change),
         server_filter_(server_filter) {}
 
  protected:
   virtual PacketFilter::Action FilterHandshake(
       const TlsHandshakeFilter::HandshakeHeader& header,
       const DataBuffer& input, DataBuffer* output) override {
     ChangeY(input, output, 0, server_filter_->prime());
     return CHANGE;
@@ -277,18 +279,18 @@ class TlsDamageDHYTest
 };
 
 TEST_P(TlsDamageDHYTest, DamageServerY) {
   EnableOnlyDheCiphers();
   if (std::get<3>(GetParam())) {
     client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
   }
   TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam());
-  server_->SetPacketFilter(
-      std::make_shared<TlsDheSkeChangeYServer>(change, true));
+  server_->SetFilter(
+      std::make_shared<TlsDheSkeChangeYServer>(server_, change, true));
 
   if (change == TlsDheSkeChangeY::kYZeroPad) {
     ExpectAlert(client_, kTlsAlertDecryptError);
   } else {
     ExpectAlert(client_, kTlsAlertIllegalParameter);
   }
   ConnectExpectFail();
   if (change == TlsDheSkeChangeY::kYZeroPad) {
@@ -307,24 +309,24 @@ TEST_P(TlsDamageDHYTest, DamageServerY) 
 }
 
 TEST_P(TlsDamageDHYTest, DamageClientY) {
   EnableOnlyDheCiphers();
   if (std::get<3>(GetParam())) {
     client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_TRUE);
   }
   // The filter on the server is required to capture the prime.
-  auto server_filter =
-      std::make_shared<TlsDheSkeChangeYServer>(TlsDheSkeChangeY::kYZero, false);
-  server_->SetPacketFilter(server_filter);
+  auto server_filter = std::make_shared<TlsDheSkeChangeYServer>(
+      server_, TlsDheSkeChangeY::kYZero, false);
+  server_->SetFilter(server_filter);
 
   // The client filter does the damage.
   TlsDheSkeChangeY::ChangeYTo change = std::get<2>(GetParam());
-  client_->SetPacketFilter(
-      std::make_shared<TlsDheSkeChangeYClient>(change, server_filter));
+  client_->SetFilter(
+      std::make_shared<TlsDheSkeChangeYClient>(client_, change, server_filter));
 
   if (change == TlsDheSkeChangeY::kYZeroPad) {
     ExpectAlert(server_, kTlsAlertDecryptError);
   } else {
     ExpectAlert(server_, kTlsAlertHandshakeFailure);
   }
   ConnectExpectFail();
   if (change == TlsDheSkeChangeY::kYZeroPad) {
@@ -353,17 +355,19 @@ INSTANTIATE_TEST_CASE_P(
                        TlsConnectTestBase::kTlsV10ToV12, kAllY, kTrueFalse));
 INSTANTIATE_TEST_CASE_P(
     DamageYDatagram, TlsDamageDHYTest,
     ::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
                        TlsConnectTestBase::kTlsV11V12, kAllY, kTrueFalse));
 
 class TlsDheSkeMakePEven : public TlsHandshakeFilter {
  public:
-  TlsDheSkeMakePEven() : TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}) {}
+  TlsDheSkeMakePEven(const std::shared_ptr<TlsAgent>& agent)
+      : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {}
+
   virtual PacketFilter::Action FilterHandshake(
       const TlsHandshakeFilter::HandshakeHeader& header,
       const DataBuffer& input, DataBuffer* output) {
     // Find the end of dh_p
     uint32_t dh_len = 0;
     EXPECT_TRUE(input.Read(0, 2, &dh_len));
     EXPECT_GT(input.len(), 2 + dh_len) << "enough space for dh_p";
     size_t offset = 2 + dh_len - 1;
@@ -374,27 +378,29 @@ class TlsDheSkeMakePEven : public TlsHan
 
     return CHANGE;
   }
 };
 
 // Even without requiring named groups, an even value for p is bad news.
 TEST_P(TlsConnectGenericPre13, MakeDhePEven) {
   EnableOnlyDheCiphers();
-  server_->SetPacketFilter(std::make_shared<TlsDheSkeMakePEven>());
+  server_->SetFilter(std::make_shared<TlsDheSkeMakePEven>(server_));
 
   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
 
   client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE);
   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
 }
 
 class TlsDheSkeZeroPadP : public TlsHandshakeFilter {
  public:
-  TlsDheSkeZeroPadP() : TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}) {}
+  TlsDheSkeZeroPadP(const std::shared_ptr<TlsAgent>& agent)
+      : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {}
+
   virtual PacketFilter::Action FilterHandshake(
       const TlsHandshakeFilter::HandshakeHeader& header,
       const DataBuffer& input, DataBuffer* output) {
     *output = input;
     uint32_t dh_len = 0;
     EXPECT_TRUE(input.Read(0, 2, &dh_len));
     static const uint8_t kZeroPad = 0;
     output->Write(0, dh_len + sizeof(kZeroPad), 2);  // increment the length
@@ -402,17 +408,17 @@ class TlsDheSkeZeroPadP : public TlsHand
 
     return CHANGE;
   }
 };
 
 // Zero padding only causes signature failure.
 TEST_P(TlsConnectGenericPre13, PadDheP) {
   EnableOnlyDheCiphers();
-  server_->SetPacketFilter(std::make_shared<TlsDheSkeZeroPadP>());
+  server_->SetFilter(std::make_shared<TlsDheSkeZeroPadP>(server_));
 
   ConnectExpectAlert(client_, kTlsAlertDecryptError);
 
   // In TLS 1.0 and 1.1, the client reports a device error.
   if (version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
     client_->CheckErrorCode(SEC_ERROR_PKCS11_DEVICE_ERROR);
   } else {
     client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
@@ -524,34 +530,35 @@ TEST_P(TlsConnectTls13, ResumeFfdhe) {
   Connect();
   SendReceive();  // Need to read so that we absorb the session ticket.
   CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
             ssl_sig_rsa_pss_rsae_sha256);
 
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   EnableOnlyDheCiphers();
-  auto clientCapture =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn);
-  client_->SetPacketFilter(clientCapture);
-  auto serverCapture =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn);
-  server_->SetPacketFilter(serverCapture);
+  auto clientCapture = std::make_shared<TlsExtensionCapture>(
+      client_, ssl_tls13_pre_shared_key_xtn);
+  client_->SetFilter(clientCapture);
+  auto serverCapture = std::make_shared<TlsExtensionCapture>(
+      server_, ssl_tls13_pre_shared_key_xtn);
+  server_->SetFilter(serverCapture);
   ExpectResumption(RESUME_TICKET);
   Connect();
   CheckKeys(ssl_kea_dh, ssl_grp_ffdhe_2048, ssl_auth_rsa_sign,
             ssl_sig_rsa_pss_rsae_sha256);
   ASSERT_LT(0UL, clientCapture->extension().len());
   ASSERT_LT(0UL, serverCapture->extension().len());
 }
 
 class TlsDheSkeChangeSignature : public TlsHandshakeFilter {
  public:
-  TlsDheSkeChangeSignature(uint16_t version, const uint8_t* data, size_t len)
-      : TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}),
+  TlsDheSkeChangeSignature(const std::shared_ptr<TlsAgent>& agent,
+                           uint16_t version, const uint8_t* data, size_t len)
+      : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}),
         version_(version),
         data_(data),
         len_(len) {}
 
  protected:
   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                                const DataBuffer& input,
                                                DataBuffer* output) {
@@ -590,16 +597,16 @@ TEST_P(TlsConnectGenericPre13, InvalidDE
       0x6d, 0xdc, 0xb8, 0x21, 0x87, 0xdd, 0x0d, 0xb9, 0x46, 0x09, 0x3e,
       0xef, 0x81, 0x5b, 0x37, 0x09, 0x39, 0xeb};
 
   Reset(TlsAgent::kServerDsa);
 
   const std::vector<SSLNamedGroup> client_groups = {ssl_grp_ffdhe_2048};
   client_->ConfigNamedGroups(client_groups);
 
-  server_->SetPacketFilter(std::make_shared<TlsDheSkeChangeSignature>(
-      version_, kBogusDheSignature, sizeof(kBogusDheSignature)));
+  server_->SetFilter(std::make_shared<TlsDheSkeChangeSignature>(
+      server_, version_, kBogusDheSignature, sizeof(kBogusDheSignature)));
 
   ConnectExpectAlert(client_, kTlsAlertDecryptError);
   client_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
 }
 
 }  // namespace nss_test
--- a/gtests/ssl_gtest/ssl_drop_unittest.cc
+++ b/gtests/ssl_gtest/ssl_drop_unittest.cc
@@ -17,82 +17,78 @@ extern "C" {
 #include "scoped_ptrs.h"
 #include "tls_connect.h"
 #include "tls_filter.h"
 #include "tls_parser.h"
 
 namespace nss_test {
 
 TEST_P(TlsConnectDatagramPre13, DropClientFirstFlightOnce) {
-  client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x1));
+  client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x1));
   Connect();
   SendReceive();
 }
 
 TEST_P(TlsConnectDatagramPre13, DropServerFirstFlightOnce) {
-  server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x1));
+  server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x1));
   Connect();
   SendReceive();
 }
 
 // This drops the first transmission from both the client and server of all
 // flights that they send.  Note: In DTLS 1.3, the shorter handshake means that
 // this will also drop some application data, so we can't call SendReceive().
 TEST_P(TlsConnectDatagramPre13, DropAllFirstTransmissions) {
-  client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x15));
-  server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x5));
+  client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x15));
+  server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x5));
   Connect();
 }
 
 // This drops the server's first flight three times.
 TEST_P(TlsConnectDatagramPre13, DropServerFirstFlightThrice) {
-  server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x7));
+  server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x7));
   Connect();
 }
 
 // This drops the client's second flight once
 TEST_P(TlsConnectDatagramPre13, DropClientSecondFlightOnce) {
-  client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x2));
+  client_->SetFilter(std::make_shared<SelectiveDropFilter>(0x2));
   Connect();
 }
 
 // This drops the client's second flight three times.
 TEST_P(TlsConnectDatagramPre13, DropClientSecondFlightThrice) {
-  client_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0xe));
+  client_->SetFilter(std::make_shared<SelectiveDropFilter>(0xe));
   Connect();
 }
 
 // This drops the server's second flight three times.
 TEST_P(TlsConnectDatagramPre13, DropServerSecondFlightThrice) {
-  server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0xe));
+  server_->SetFilter(std::make_shared<SelectiveDropFilter>(0xe));
   Connect();
 }
 
 class TlsDropDatagram13 : public TlsConnectDatagram13 {
  public:
   TlsDropDatagram13()
       : client_filters_(),
         server_filters_(),
         expected_client_acks_(0),
         expected_server_acks_(1) {}
 
-  void SetUp() {
+  void SetUp() override {
     TlsConnectDatagram13::SetUp();
     ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
     SetFilters();
   }
 
   void SetFilters() {
     EnsureTlsSetup();
-    client_->SetPacketFilter(client_filters_.chain_);
-    client_filters_.ack_->SetAgent(client_.get());
-    client_filters_.ack_->EnableDecryption();
-    server_->SetPacketFilter(server_filters_.chain_);
-    server_filters_.ack_->SetAgent(server_.get());
-    server_filters_.ack_->EnableDecryption();
+    client_filters_.Init(client_);
+    server_filters_.Init(server_);
   }
 
   void HandshakeAndAck(const std::shared_ptr<TlsAgent>& agent) {
     agent->Handshake();  // Read flight.
     ShiftDtlsTimers();
     agent->Handshake();  // Generate ACK.
   }
 
@@ -114,21 +110,27 @@ class TlsDropDatagram13 : public TlsConn
                void* arg) -> SECStatus { return SECSuccess; },
             nullptr));
   }
 
  protected:
   class DropAckChain {
    public:
     DropAckChain()
-        : records_(std::make_shared<TlsRecordRecorder>()),
-          ack_(std::make_shared<TlsRecordRecorder>(content_ack)),
-          drop_(std::make_shared<SelectiveRecordDropFilter>(0, false)),
-          chain_(std::make_shared<ChainedPacketFilter>(
-              ChainedPacketFilterInit({records_, ack_, drop_}))) {}
+        : records_(nullptr), ack_(nullptr), drop_(nullptr), chain_(nullptr) {}
+
+    void Init(const std::shared_ptr<TlsAgent>& agent) {
+      records_ = std::make_shared<TlsRecordRecorder>(agent);
+      ack_ = std::make_shared<TlsRecordRecorder>(agent, content_ack);
+      ack_->EnableDecryption();
+      drop_ = std::make_shared<SelectiveRecordDropFilter>(agent, 0, false);
+      chain_ = std::make_shared<ChainedPacketFilter>(
+          ChainedPacketFilterInit({records_, ack_, drop_}));
+      agent->SetFilter(chain_);
+    }
 
     const TlsRecord& record(size_t i) const { return records_->record(i); }
 
     std::shared_ptr<TlsRecordRecorder> records_;
     std::shared_ptr<TlsRecordRecorder> ack_;
     std::shared_ptr<SelectiveRecordDropFilter> drop_;
     std::shared_ptr<PacketFilter> chain_;
   };
@@ -222,17 +224,17 @@ TEST_F(TlsDropDatagram13, DropServerFirs
 TEST_F(TlsDropDatagram13, DropServerSecondRecordOnce) {
   server_filters_.drop_->Reset({1});
   StartConnect();
   client_->Handshake();
   server_->Handshake();
   HandshakeAndAck(client_);
   expected_client_acks_ = 1;
   CheckedHandshakeSendReceive();
-  CheckAcks(client_filters_, 0, {0});
+  CheckAcks(client_filters_, 0, {0});  // ServerHello
   CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
 }
 
 // Drop the server ACK and verify that the client retransmits
 // the ClientHello.
 TEST_F(TlsDropDatagram13, DropServerAckOnce) {
   StartConnect();
   client_->Handshake();
@@ -252,17 +254,17 @@ TEST_F(TlsDropDatagram13, DropServerAckO
   uint8_t buf[1];
   PRInt32 rv = PR_Read(client_->ssl_fd(), buf, sizeof(buf));
   expected_server_acks_ = 2;
   EXPECT_GT(0, rv);
   EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
   CheckPostHandshake();
   // There should be two copies of the finished ACK
   CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
-  CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
+  CheckAcks(server_filters_, 1, {0x0002000000000000ULL});
 }
 
 // Drop the client certificate verify.
 TEST_F(TlsDropDatagram13, DropClientCertVerify) {
   StartConnect();
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   client_->Handshake();
@@ -271,20 +273,19 @@ TEST_F(TlsDropDatagram13, DropClientCert
   client_filters_.drop_->Reset({1});
   expected_server_acks_ = 2;
   CheckedHandshakeSendReceive();
   // Ack of the Cert.
   CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
   // Ack of the whole client handshake.
   CheckAcks(
       server_filters_, 1,
-      {0x0002000000000000ULL,  // CH (we drop everything after this on client)
-       0x0002000000000003ULL,  // CT (2)
-       0x0002000000000004ULL}  // FIN (2)
-      );
+      {0x0002000000000000ULL,    // CH (we drop everything after this on client)
+       0x0002000000000003ULL,    // CT (2)
+       0x0002000000000004ULL});  // FIN (2)
 }
 
 // Shrink the MTU down so that certs get split and drop the first piece.
 TEST_F(TlsDropDatagram13, DropFirstHalfOfServerCertificate) {
   server_filters_.drop_->Reset({2});
   StartConnect();
   ShrinkPostServerHelloMtu();
   client_->Handshake();
@@ -298,20 +299,19 @@ TEST_F(TlsDropDatagram13, DropFirstHalfO
   HandshakeAndAck(client_);
   server_->Handshake();                               // Retransmit
   EXPECT_EQ(3UL, server_filters_.records_->count());  // CT2, CV, FIN
   // Check that the first record is CT1 (which is identical to the same
   // as the previous CT1).
   EXPECT_EQ(ct1_size, server_filters_.record(0).buffer.len());
   CheckedHandshakeSendReceive();
   CheckAcks(client_filters_, 0,
-            {0,                      // SH
-             0x0002000000000000ULL,  // EE
-             0x0002000000000002ULL}  // CT2
-            );
+            {0,                        // SH
+             0x0002000000000000ULL,    // EE
+             0x0002000000000002ULL});  // CT2
   CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
 }
 
 // Shrink the MTU down so that certs get split and drop the second piece.
 TEST_F(TlsDropDatagram13, DropSecondHalfOfServerCertificate) {
   server_filters_.drop_->Reset({3});
   StartConnect();
   ShrinkPostServerHelloMtu();
@@ -535,17 +535,20 @@ TEST_F(TlsDropDatagram13, NoDropsDuringZ
   client_->Set0RttEnabled(true);
   server_->Set0RttEnabled(true);
   ExpectResumption(RESUME_TICKET);
   ZeroRttSendReceive(true, true);
   Handshake();
   ExpectEarlyDataAccepted(true);
   CheckConnected();
   SendReceive();
-  CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
+  EXPECT_EQ(0U, client_filters_.ack_->count());
+  CheckAcks(server_filters_, 0,
+            {0x0001000000000001ULL,    // EOED
+             0x0002000000000000ULL});  // Finished
 }
 
 TEST_F(TlsDropDatagram13, DropEEDuringZeroRtt) {
   SetupForZeroRtt();
   SetFilters();
   std::cerr << "Starting second handshake" << std::endl;
   client_->Set0RttEnabled(true);
   server_->Set0RttEnabled(true);
@@ -553,17 +556,19 @@ TEST_F(TlsDropDatagram13, DropEEDuringZe
   server_filters_.drop_->Reset({1});
   ZeroRttSendReceive(true, true);
   HandshakeAndAck(client_);
   Handshake();
   ExpectEarlyDataAccepted(true);
   CheckConnected();
   SendReceive();
   CheckAcks(client_filters_, 0, {0});
-  CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
+  CheckAcks(server_filters_, 0,
+            {0x0001000000000002ULL,    // EOED
+             0x0002000000000000ULL});  // Finished
 }
 
 class TlsReorderDatagram13 : public TlsDropDatagram13 {
  public:
   TlsReorderDatagram13() {}
 
   // Send records from the records buffer in the given order.
   void ReSend(TlsAgent::Role side, std::vector<size_t> indices) {
@@ -683,16 +688,17 @@ TEST_F(TlsDropDatagram13, SendOutOfOrder
   auto spec = capturer.spec(0);
   ASSERT_NE(nullptr, spec.get());
   ASSERT_EQ(2, spec->epoch());
   ASSERT_TRUE(client_->SendEncryptedRecord(
       spec, SSL_LIBRARY_VERSION_DTLS_1_2_WIRE, 0x0002000000000002,
       kTlsHandshakeType, DataBuffer(buf, sizeof(buf))));
   server_->Handshake();
   EXPECT_EQ(2UL, server_filters_.ack_->count());
+  // The server acknowledges client Finished twice.
   CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
   CheckAcks(server_filters_, 1, {0x0002000000000000ULL});
 }
 
 // Shrink the MTU down so that certs get split and then swap the first and
 // second pieces of the server certificate.
 TEST_F(TlsReorderDatagram13, ReorderServerCertificate) {
   StartConnect();
@@ -741,17 +747,19 @@ TEST_F(TlsReorderDatagram13, DataAfterEO
   // The server still hasn't received anything at this point.
   EXPECT_EQ(3UL, client_filters_.records_->count());  // data, EOED, FIN
   EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
   EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state());
   // Now re-send the client's messages: EOED, data, FIN
   ReSend(TlsAgent::CLIENT, std::vector<size_t>({1, 0, 2}));
   server_->Handshake();
   CheckConnected();
-  CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
+  EXPECT_EQ(0U, client_filters_.ack_->count());
+  // Acknowledgements for EOED and Finished.
+  CheckAcks(server_filters_, 0, {0x0001000000000002ULL, 0x0002000000000000ULL});
   uint8_t buf[8];
   rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf));
   EXPECT_EQ(-1, rv);
   EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
 }
 
 TEST_F(TlsReorderDatagram13, DataAfterFinDuringZeroRtt) {
   SetupForZeroRtt();
@@ -778,17 +786,19 @@ TEST_F(TlsReorderDatagram13, DataAfterFi
   // The server still hasn't received anything at this point.
   EXPECT_EQ(3UL, client_filters_.records_->count());  // EOED, FIN, Data
   EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
   EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state());
   // Now re-send the client's messages: EOED, FIN, Data
   ReSend(TlsAgent::CLIENT, std::vector<size_t>({1, 2, 0}));
   server_->Handshake();
   CheckConnected();
-  CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
+  EXPECT_EQ(0U, client_filters_.ack_->count());
+  // Acknowledgements for EOED and Finished.
+  CheckAcks(server_filters_, 0, {0x0001000000000002ULL, 0x0002000000000000ULL});
   uint8_t buf[8];
   rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf));
   EXPECT_EQ(-1, rv);
   EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
 }
 
 static void GetCipherAndLimit(uint16_t version, uint16_t* cipher,
                               uint64_t* limit = nullptr) {
--- a/gtests/ssl_gtest/ssl_ecdh_unittest.cc
+++ b/gtests/ssl_gtest/ssl_ecdh_unittest.cc
@@ -70,19 +70,19 @@ TEST_P(TlsConnectGeneric, ConnectEcdheP3
   Connect();
   CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
             ssl_sig_rsa_pss_rsae_sha256);
 }
 
 // This causes a HelloRetryRequest in TLS 1.3.  Earlier versions don't care.
 TEST_P(TlsConnectGeneric, ConnectEcdheP384Server) {
   EnsureTlsSetup();
-  auto hrr_capture = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      kTlsHandshakeHelloRetryRequest);
-  server_->SetPacketFilter(hrr_capture);
+  auto hrr_capture = std::make_shared<TlsHandshakeRecorder>(
+      server_, kTlsHandshakeHelloRetryRequest);
+  server_->SetFilter(hrr_capture);
   const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
   server_->ConfigNamedGroups(groups);
   Connect();
   CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
             ssl_sig_rsa_pss_rsae_sha256);
   EXPECT_EQ(version_ == SSL_LIBRARY_VERSION_TLS_1_3,
             hrr_capture->buffer().len() != 0);
 }
@@ -188,18 +188,18 @@ TEST_P(TlsConnectGenericPre13, P384Prior
   Connect();
 
   CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_rsa_sign,
             ssl_sig_rsa_pss_rsae_sha256);
 }
 
 class TlsKeyExchangeGroupCapture : public TlsHandshakeFilter {
  public:
-  TlsKeyExchangeGroupCapture()
-      : TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}),
+  TlsKeyExchangeGroupCapture(const std::shared_ptr<TlsAgent> &agent)
+      : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}),
         group_(ssl_grp_none) {}
 
   SSLNamedGroup group() const { return group_; }
 
  protected:
   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
                                                const DataBuffer &input,
                                                DataBuffer *output) {
@@ -216,33 +216,33 @@ class TlsKeyExchangeGroupCapture : publi
  private:
   SSLNamedGroup group_;
 };
 
 // If we strip the client's supported groups extension, the server should assume
 // P-256 is supported by the client (<= 1.2 only).
 TEST_P(TlsConnectGenericPre13, DropSupportedGroupExtensionP256) {
   EnsureTlsSetup();
-  client_->SetPacketFilter(
-      std::make_shared<TlsExtensionDropper>(ssl_supported_groups_xtn));
-  auto group_capture = std::make_shared<TlsKeyExchangeGroupCapture>();
-  server_->SetPacketFilter(group_capture);
+  client_->SetFilter(
+      std::make_shared<TlsExtensionDropper>(client_, ssl_supported_groups_xtn));
+  auto group_capture = std::make_shared<TlsKeyExchangeGroupCapture>(server_);
+  server_->SetFilter(group_capture);
 
   ConnectExpectAlert(server_, kTlsAlertDecryptError);
   client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
   server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
 
   EXPECT_EQ(ssl_grp_ec_secp256r1, group_capture->group());
 }
 
 // Supported groups is mandatory in TLS 1.3.
 TEST_P(TlsConnectTls13, DropSupportedGroupExtension) {
   EnsureTlsSetup();
-  client_->SetPacketFilter(
-      std::make_shared<TlsExtensionDropper>(ssl_supported_groups_xtn));
+  client_->SetFilter(
+      std::make_shared<TlsExtensionDropper>(client_, ssl_supported_groups_xtn));
   ConnectExpectAlert(server_, kTlsAlertMissingExtension);
   client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT);
   server_->CheckErrorCode(SSL_ERROR_MISSING_SUPPORTED_GROUPS_EXTENSION);
 }
 
 // If we only have a lame group, we fall back to static RSA.
 TEST_P(TlsConnectGenericPre13, UseLameGroup) {
   const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp192r1};
@@ -511,33 +511,35 @@ TEST_P(TlsKeyExchangeTest13, MultipleCli
   const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519,
                                              ssl_grp_ec_secp256r1};
   CheckKEXDetails(client_groups, shares);
 }
 
 // Replace the point in the client key exchange message with an empty one
 class ECCClientKEXFilter : public TlsHandshakeFilter {
  public:
-  ECCClientKEXFilter() : TlsHandshakeFilter({kTlsHandshakeClientKeyExchange}) {}
+  ECCClientKEXFilter(const std::shared_ptr<TlsAgent> &client)
+      : TlsHandshakeFilter(client, {kTlsHandshakeClientKeyExchange}) {}
 
  protected:
   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
                                                const DataBuffer &input,
                                                DataBuffer *output) {
     // Replace the client key exchange message with an empty point
     output->Allocate(1);
     output->Write(0, 0U, 1);  // set point length 0
     return CHANGE;
   }
 };
 
 // Replace the point in the server key exchange message with an empty one
 class ECCServerKEXFilter : public TlsHandshakeFilter {
  public:
-  ECCServerKEXFilter() : TlsHandshakeFilter({kTlsHandshakeServerKeyExchange}) {}
+  ECCServerKEXFilter(const std::shared_ptr<TlsAgent> &server)
+      : TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}) {}
 
  protected:
   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
                                                const DataBuffer &input,
                                                DataBuffer *output) {
     // Replace the server key exchange message with an empty point
     output->Allocate(4);
     output->Write(0, 3U, 1);  // named curve
@@ -545,25 +547,23 @@ class ECCServerKEXFilter : public TlsHan
     EXPECT_TRUE(input.Read(1, 2, &curve));  // get curve id
     output->Write(1, curve, 2);             // write curve id
     output->Write(3, 0U, 1);                // point length 0
     return CHANGE;
   }
 };
 
 TEST_P(TlsConnectGenericPre13, ConnectECDHEmptyServerPoint) {
-  // add packet filter
-  server_->SetPacketFilter(std::make_shared<ECCServerKEXFilter>());
+  server_->SetFilter(std::make_shared<ECCServerKEXFilter>(server_));
   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
   client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH);
 }
 
 TEST_P(TlsConnectGenericPre13, ConnectECDHEmptyClientPoint) {
-  // add packet filter
-  client_->SetPacketFilter(std::make_shared<ECCClientKEXFilter>());
+  client_->SetFilter(std::make_shared<ECCClientKEXFilter>(client_));
   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
   server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH);
 }
 
 INSTANTIATE_TEST_CASE_P(KeyExchangeTest, TlsKeyExchangeTest,
                         ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
                                            TlsConnectTestBase::kTlsV11Plus));
 
--- a/gtests/ssl_gtest/ssl_extension_unittest.cc
+++ b/gtests/ssl_gtest/ssl_extension_unittest.cc
@@ -14,18 +14,19 @@
 #include "tls_connect.h"
 #include "tls_filter.h"
 #include "tls_parser.h"
 
 namespace nss_test {
 
 class TlsExtensionTruncator : public TlsExtensionFilter {
  public:
-  TlsExtensionTruncator(uint16_t extension, size_t length)
-      : extension_(extension), length_(length) {}
+  TlsExtensionTruncator(const std::shared_ptr<TlsAgent>& agent,
+                        uint16_t extension, size_t length)
+      : TlsExtensionFilter(agent), extension_(extension), length_(length) {}
   virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
                                                const DataBuffer& input,
                                                DataBuffer* output) {
     if (extension_type != extension_) {
       return KEEP;
     }
     if (input.len() <= length_) {
       return KEEP;
@@ -37,18 +38,19 @@ class TlsExtensionTruncator : public Tls
 
  private:
   uint16_t extension_;
   size_t length_;
 };
 
 class TlsExtensionDamager : public TlsExtensionFilter {
  public:
-  TlsExtensionDamager(uint16_t extension, size_t index)
-      : extension_(extension), index_(index) {}
+  TlsExtensionDamager(const std::shared_ptr<TlsAgent>& agent,
+                      uint16_t extension, size_t index)
+      : TlsExtensionFilter(agent), extension_(extension), index_(index) {}
   virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
                                                const DataBuffer& input,
                                                DataBuffer* output) {
     if (extension_type != extension_) {
       return KEEP;
     }
 
     *output = input;
@@ -58,18 +60,21 @@ class TlsExtensionDamager : public TlsEx
 
  private:
   uint16_t extension_;
   size_t index_;
 };
 
 class TlsExtensionAppender : public TlsHandshakeFilter {
  public:
-  TlsExtensionAppender(uint8_t handshake_type, uint16_t ext, DataBuffer& data)
-      : TlsHandshakeFilter({handshake_type}), extension_(ext), data_(data) {}
+  TlsExtensionAppender(const std::shared_ptr<TlsAgent>& agent,
+                       uint8_t handshake_type, uint16_t ext, DataBuffer& data)
+      : TlsHandshakeFilter(agent, {handshake_type}),
+        extension_(ext),
+        data_(data) {}
 
   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                                const DataBuffer& input,
                                                DataBuffer* output) {
     TlsParser parser(input);
     if (!TlsExtensionFilter::FindExtensions(&parser, header)) {
       return KEEP;
     }
@@ -119,23 +124,23 @@ class TlsExtensionAppender : public TlsH
 
 class TlsExtensionTestBase : public TlsConnectTestBase {
  protected:
   TlsExtensionTestBase(SSLProtocolVariant variant, uint16_t version)
       : TlsConnectTestBase(variant, version) {}
 
   void ClientHelloErrorTest(std::shared_ptr<PacketFilter> filter,
                             uint8_t desc = kTlsAlertDecodeError) {
-    client_->SetPacketFilter(filter);
+    client_->SetFilter(filter);
     ConnectExpectAlert(server_, desc);
   }
 
   void ServerHelloErrorTest(std::shared_ptr<PacketFilter> filter,
                             uint8_t desc = kTlsAlertDecodeError) {
-    server_->SetPacketFilter(filter);
+    server_->SetFilter(filter);
     ConnectExpectAlert(client_, desc);
   }
 
   static void InitSimpleSni(DataBuffer* extension) {
     const char* name = "host.name";
     const size_t namelen = PL_strlen(name);
     extension->Allocate(namelen + 5);
     extension->Write(0, namelen + 3, 2);
@@ -151,17 +156,17 @@ class TlsExtensionTestBase : public TlsC
     static const std::vector<SSLNamedGroup> server_groups = {
         ssl_grp_ec_curve25519, ssl_grp_ec_secp384r1};
     client_->ConfigNamedGroups(client_groups);
     server_->ConfigNamedGroups(server_groups);
     EnsureTlsSetup();
     StartConnect();
     client_->Handshake();  // Send ClientHello
     server_->Handshake();  // Send HRR.
-    client_->SetPacketFilter(std::make_shared<TlsExtensionDropper>(type));
+    client_->SetFilter(std::make_shared<TlsExtensionDropper>(client_, type));
     Handshake();
     client_->CheckErrorCode(client_error);
     server_->CheckErrorCode(server_error);
   }
 };
 
 class TlsExtensionTestDtls : public TlsExtensionTestBase,
                              public ::testing::WithParamInterface<uint16_t> {
@@ -192,30 +197,30 @@ class TlsExtensionTest13
     : public TlsExtensionTestBase,
       public ::testing::WithParamInterface<SSLProtocolVariant> {
  public:
   TlsExtensionTest13()
       : TlsExtensionTestBase(GetParam(), SSL_LIBRARY_VERSION_TLS_1_3) {}
 
   void ConnectWithBogusVersionList(const uint8_t* buf, size_t len) {
     DataBuffer versions_buf(buf, len);
-    client_->SetPacketFilter(std::make_shared<TlsExtensionReplacer>(
-        ssl_tls13_supported_versions_xtn, versions_buf));
+    client_->SetFilter(std::make_shared<TlsExtensionReplacer>(
+        client_, ssl_tls13_supported_versions_xtn, versions_buf));
     ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
     client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
     server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
   }
 
   void ConnectWithReplacementVersionList(uint16_t version) {
     DataBuffer versions_buf;
 
     size_t index = versions_buf.Write(0, 2, 1);
     versions_buf.Write(index, version, 2);
-    client_->SetPacketFilter(std::make_shared<TlsExtensionReplacer>(
-        ssl_tls13_supported_versions_xtn, versions_buf));
+    client_->SetFilter(std::make_shared<TlsExtensionReplacer>(
+        client_, ssl_tls13_supported_versions_xtn, versions_buf));
     ConnectExpectFail();
   }
 };
 
 class TlsExtensionTest13Stream : public TlsExtensionTestBase {
  public:
   TlsExtensionTest13Stream()
       : TlsExtensionTestBase(ssl_variant_stream, SSL_LIBRARY_VERSION_TLS_1_3) {}
@@ -236,97 +241,97 @@ class TlsExtensionTestPre13 : public Tls
  public:
   TlsExtensionTestPre13()
       : TlsExtensionTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {
   }
 };
 
 TEST_P(TlsExtensionTestGeneric, DamageSniLength) {
   ClientHelloErrorTest(
-      std::make_shared<TlsExtensionDamager>(ssl_server_name_xtn, 1));
+      std::make_shared<TlsExtensionDamager>(client_, ssl_server_name_xtn, 1));
 }
 
 TEST_P(TlsExtensionTestGeneric, DamageSniHostLength) {
   ClientHelloErrorTest(
-      std::make_shared<TlsExtensionDamager>(ssl_server_name_xtn, 4));
+      std::make_shared<TlsExtensionDamager>(client_, ssl_server_name_xtn, 4));
 }
 
 TEST_P(TlsExtensionTestGeneric, TruncateSni) {
   ClientHelloErrorTest(
-      std::make_shared<TlsExtensionTruncator>(ssl_server_name_xtn, 7));
+      std::make_shared<TlsExtensionTruncator>(client_, ssl_server_name_xtn, 7));
 }
 
 // A valid extension that appears twice will be reported as unsupported.
 TEST_P(TlsExtensionTestGeneric, RepeatSni) {
   DataBuffer extension;
   InitSimpleSni(&extension);
-  ClientHelloErrorTest(
-      std::make_shared<TlsExtensionInjector>(ssl_server_name_xtn, extension),
-      kTlsAlertIllegalParameter);
+  ClientHelloErrorTest(std::make_shared<TlsExtensionInjector>(
+                           client_, ssl_server_name_xtn, extension),
+                       kTlsAlertIllegalParameter);
 }
 
 // An SNI entry with zero length is considered invalid (strangely, not if it is
 // the last entry, which is probably a bug).
 TEST_P(TlsExtensionTestGeneric, BadSni) {
   DataBuffer simple;
   InitSimpleSni(&simple);
   DataBuffer extension;
   extension.Allocate(simple.len() + 3);
   extension.Write(0, static_cast<uint32_t>(0), 3);
   extension.Write(3, simple);
-  ClientHelloErrorTest(
-      std::make_shared<TlsExtensionReplacer>(ssl_server_name_xtn, extension));
+  ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
+      client_, ssl_server_name_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestGeneric, EmptySni) {
   DataBuffer extension;
   extension.Allocate(2);
   extension.Write(0, static_cast<uint32_t>(0), 2);
-  ClientHelloErrorTest(
-      std::make_shared<TlsExtensionReplacer>(ssl_server_name_xtn, extension));
+  ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
+      client_, ssl_server_name_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestGeneric, EmptyAlpnExtension) {
   EnableAlpn();
   DataBuffer extension;
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-                           ssl_app_layer_protocol_xtn, extension),
+                           client_, ssl_app_layer_protocol_xtn, extension),
                        kTlsAlertIllegalParameter);
 }
 
 // An empty ALPN isn't considered bad, though it does lead to there being no
 // protocol for the server to select.
 TEST_P(TlsExtensionTestGeneric, EmptyAlpnList) {
   EnableAlpn();
   const uint8_t val[] = {0x00, 0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-                           ssl_app_layer_protocol_xtn, extension),
+                           client_, ssl_app_layer_protocol_xtn, extension),
                        kTlsAlertNoApplicationProtocol);
 }
 
 TEST_P(TlsExtensionTestGeneric, OneByteAlpn) {
   EnableAlpn();
-  ClientHelloErrorTest(
-      std::make_shared<TlsExtensionTruncator>(ssl_app_layer_protocol_xtn, 1));
+  ClientHelloErrorTest(std::make_shared<TlsExtensionTruncator>(
+      client_, ssl_app_layer_protocol_xtn, 1));
 }
 
 TEST_P(TlsExtensionTestGeneric, AlpnMissingValue) {
   EnableAlpn();
   // This will leave the length of the second entry, but no value.
-  ClientHelloErrorTest(
-      std::make_shared<TlsExtensionTruncator>(ssl_app_layer_protocol_xtn, 5));
+  ClientHelloErrorTest(std::make_shared<TlsExtensionTruncator>(
+      client_, ssl_app_layer_protocol_xtn, 5));
 }
 
 TEST_P(TlsExtensionTestGeneric, AlpnZeroLength) {
   EnableAlpn();
   const uint8_t val[] = {0x01, 0x61, 0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_app_layer_protocol_xtn, extension));
+      client_, ssl_app_layer_protocol_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestGeneric, AlpnMismatch) {
   const uint8_t client_alpn[] = {0x01, 0x61};
   client_->EnableAlpn(client_alpn, sizeof(client_alpn));
   const uint8_t server_alpn[] = {0x02, 0x61, 0x62};
   server_->EnableAlpn(server_alpn, sizeof(server_alpn));
 
@@ -335,199 +340,199 @@ TEST_P(TlsExtensionTestGeneric, AlpnMism
 
 // Many of these tests fail in TLS 1.3 because the extension is encrypted, which
 // prevents modification of the value from the ServerHello.
 TEST_P(TlsExtensionTestPre13, AlpnReturnedEmptyList) {
   EnableAlpn();
   const uint8_t val[] = {0x00, 0x00};
   DataBuffer extension(val, sizeof(val));
   ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_app_layer_protocol_xtn, extension));
+      server_, ssl_app_layer_protocol_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, AlpnReturnedEmptyName) {
   EnableAlpn();
   const uint8_t val[] = {0x00, 0x01, 0x00};
   DataBuffer extension(val, sizeof(val));
   ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_app_layer_protocol_xtn, extension));
+      server_, ssl_app_layer_protocol_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, AlpnReturnedListTrailingData) {
   EnableAlpn();
   const uint8_t val[] = {0x00, 0x02, 0x01, 0x61, 0x00};
   DataBuffer extension(val, sizeof(val));
   ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_app_layer_protocol_xtn, extension));
+      server_, ssl_app_layer_protocol_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, AlpnReturnedExtraEntry) {
   EnableAlpn();
   const uint8_t val[] = {0x00, 0x04, 0x01, 0x61, 0x01, 0x62};
   DataBuffer extension(val, sizeof(val));
   ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_app_layer_protocol_xtn, extension));
+      server_, ssl_app_layer_protocol_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, AlpnReturnedBadListLength) {
   EnableAlpn();
   const uint8_t val[] = {0x00, 0x99, 0x01, 0x61, 0x00};
   DataBuffer extension(val, sizeof(val));
   ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_app_layer_protocol_xtn, extension));
+      server_, ssl_app_layer_protocol_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, AlpnReturnedBadNameLength) {
   EnableAlpn();
   const uint8_t val[] = {0x00, 0x02, 0x99, 0x61};
   DataBuffer extension(val, sizeof(val));
   ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_app_layer_protocol_xtn, extension));
+      server_, ssl_app_layer_protocol_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, AlpnReturnedUnknownName) {
   EnableAlpn();
   const uint8_t val[] = {0x00, 0x02, 0x01, 0x67};
   DataBuffer extension(val, sizeof(val));
   ServerHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-                           ssl_app_layer_protocol_xtn, extension),
+                           server_, ssl_app_layer_protocol_xtn, extension),
                        kTlsAlertIllegalParameter);
 }
 
 TEST_P(TlsExtensionTestDtls, SrtpShort) {
   EnableSrtp();
   ClientHelloErrorTest(
-      std::make_shared<TlsExtensionTruncator>(ssl_use_srtp_xtn, 3));
+      std::make_shared<TlsExtensionTruncator>(client_, ssl_use_srtp_xtn, 3));
 }
 
 TEST_P(TlsExtensionTestDtls, SrtpOdd) {
   EnableSrtp();
   const uint8_t val[] = {0x00, 0x01, 0xff, 0x00};
   DataBuffer extension(val, sizeof(val));
-  ClientHelloErrorTest(
-      std::make_shared<TlsExtensionReplacer>(ssl_use_srtp_xtn, extension));
+  ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
+      client_, ssl_use_srtp_xtn, extension));
 }
 
 TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsBadLength) {
   const uint8_t val[] = {0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_signature_algorithms_xtn, extension));
+      client_, ssl_signature_algorithms_xtn, extension));
 }
 
 TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsTrailingData) {
   const uint8_t val[] = {0x00, 0x02, 0x04, 0x01, 0x00};  // sha-256, rsa
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_signature_algorithms_xtn, extension));
+      client_, ssl_signature_algorithms_xtn, extension));
 }
 
 TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsEmpty) {
   const uint8_t val[] = {0x00, 0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-                           ssl_signature_algorithms_xtn, extension),
+                           client_, ssl_signature_algorithms_xtn, extension),
                        kTlsAlertHandshakeFailure);
 }
 
 TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsNoOverlap) {
   const uint8_t val[] = {0x00, 0x02, 0xff, 0xff};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-                           ssl_signature_algorithms_xtn, extension),
+                           client_, ssl_signature_algorithms_xtn, extension),
                        kTlsAlertHandshakeFailure);
 }
 
 TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsOddLength) {
   const uint8_t val[] = {0x00, 0x01, 0x04};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_signature_algorithms_xtn, extension));
+      client_, ssl_signature_algorithms_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestGeneric, NoSupportedGroups) {
   ClientHelloErrorTest(
-      std::make_shared<TlsExtensionDropper>(ssl_supported_groups_xtn),
+      std::make_shared<TlsExtensionDropper>(client_, ssl_supported_groups_xtn),
       version_ < SSL_LIBRARY_VERSION_TLS_1_3 ? kTlsAlertDecryptError
                                              : kTlsAlertMissingExtension);
 }
 
 TEST_P(TlsExtensionTestGeneric, SupportedCurvesShort) {
   const uint8_t val[] = {0x00, 0x01, 0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_elliptic_curves_xtn, extension));
+      client_, ssl_elliptic_curves_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestGeneric, SupportedCurvesBadLength) {
   const uint8_t val[] = {0x09, 0x99, 0x00, 0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_elliptic_curves_xtn, extension));
+      client_, ssl_elliptic_curves_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestGeneric, SupportedCurvesTrailingData) {
   const uint8_t val[] = {0x00, 0x02, 0x00, 0x00, 0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_elliptic_curves_xtn, extension));
+      client_, ssl_elliptic_curves_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, SupportedPointsEmpty) {
   const uint8_t val[] = {0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_ec_point_formats_xtn, extension));
+      client_, ssl_ec_point_formats_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, SupportedPointsBadLength) {
   const uint8_t val[] = {0x99, 0x00, 0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_ec_point_formats_xtn, extension));
+      client_, ssl_ec_point_formats_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, SupportedPointsTrailingData) {
   const uint8_t val[] = {0x01, 0x00, 0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_ec_point_formats_xtn, extension));
+      client_, ssl_ec_point_formats_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, RenegotiationInfoBadLength) {
   const uint8_t val[] = {0x99};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_renegotiation_info_xtn, extension));
+      client_, ssl_renegotiation_info_xtn, extension));
 }
 
 TEST_P(TlsExtensionTestPre13, RenegotiationInfoMismatch) {
   const uint8_t val[] = {0x01, 0x00};
   DataBuffer extension(val, sizeof(val));
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_renegotiation_info_xtn, extension));
+      client_, ssl_renegotiation_info_xtn, extension));
 }
 
 // The extension has to contain a length.
 TEST_P(TlsExtensionTestPre13, RenegotiationInfoExtensionEmpty) {
   DataBuffer extension;
   ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
-      ssl_renegotiation_info_xtn, extension));
+      client_, ssl_renegotiation_info_xtn, extension));
 }
 
 // This only works on TLS 1.2, since it relies on static RSA; otherwise libssl
 // picks the wrong cipher suite.
 TEST_P(TlsExtensionTest12, SignatureAlgorithmConfiguration) {
   const SSLSignatureScheme schemes[] = {ssl_sig_rsa_pss_rsae_sha512,
                                         ssl_sig_rsa_pss_rsae_sha384};
 
-  auto capture =
-      std::make_shared<TlsExtensionCapture>(ssl_signature_algorithms_xtn);
+  auto capture = std::make_shared<TlsExtensionCapture>(
+      client_, ssl_signature_algorithms_xtn);
   client_->SetSignatureSchemes(schemes, PR_ARRAY_SIZE(schemes));
-  client_->SetPacketFilter(capture);
+  client_->SetFilter(capture);
   EnableOnlyStaticRsaCiphers();
   Connect();
 
   const DataBuffer& ext = capture->extension();
   EXPECT_EQ(2 + PR_ARRAY_SIZE(schemes) * 2, ext.len());
   for (size_t i = 0, cursor = 2;
        i < PR_ARRAY_SIZE(schemes) && cursor < ext.len(); ++i) {
     uint32_t v = 0;
@@ -535,29 +540,29 @@ TEST_P(TlsExtensionTest12, SignatureAlgo
     cursor += 2;
     EXPECT_EQ(schemes[i], static_cast<SSLSignatureScheme>(v));
   }
 }
 
 // Temporary test to verify that we choke on an empty ClientKeyShare.
 // This test will fail when we implement HelloRetryRequest.
 TEST_P(TlsExtensionTest13, EmptyClientKeyShare) {
-  ClientHelloErrorTest(
-      std::make_shared<TlsExtensionTruncator>(ssl_tls13_key_share_xtn, 2),
-      kTlsAlertHandshakeFailure);
+  ClientHelloErrorTest(std::make_shared<TlsExtensionTruncator>(
+                           client_, ssl_tls13_key_share_xtn, 2),
+                       kTlsAlertHandshakeFailure);
 }
 
 // These tests only work in stream mode because the client sends a
 // cleartext alert which causes a MAC error on the server. With
 // stream this causes handshake failure but with datagram, the
 // packet gets dropped.
 TEST_F(TlsExtensionTest13Stream, DropServerKeyShare) {
   EnsureTlsSetup();
-  server_->SetPacketFilter(
-      std::make_shared<TlsExtensionDropper>(ssl_tls13_key_share_xtn));
+  server_->SetFilter(
+      std::make_shared<TlsExtensionDropper>(server_, ssl_tls13_key_share_xtn));
   client_->ExpectSendAlert(kTlsAlertMissingExtension);
   server_->ExpectSendAlert(kTlsAlertBadRecordMac);
   ConnectExpectFail();
   EXPECT_EQ(SSL_ERROR_MISSING_KEY_SHARE, client_->error_code());
   EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code());
 }
 
 TEST_F(TlsExtensionTest13Stream, WrongServerKeyShare) {
@@ -567,18 +572,18 @@ TEST_F(TlsExtensionTest13Stream, WrongSe
       wrong_group >> 8,
       wrong_group & 0xff,  // Group we didn't offer.
       0x00,
       0x02,  // length = 2
       0x01,
       0x02};
   DataBuffer buf(key_share, sizeof(key_share));
   EnsureTlsSetup();
-  server_->SetPacketFilter(
-      std::make_shared<TlsExtensionReplacer>(ssl_tls13_key_share_xtn, buf));
+  server_->SetFilter(std::make_shared<TlsExtensionReplacer>(
+      server_, ssl_tls13_key_share_xtn, buf));
   client_->ExpectSendAlert(kTlsAlertIllegalParameter);
   server_->ExpectSendAlert(kTlsAlertBadRecordMac);
   ConnectExpectFail();
   EXPECT_EQ(SSL_ERROR_RX_MALFORMED_KEY_SHARE, client_->error_code());
   EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code());
 }
 
 // TODO(ekr@rtfm.com): This is the wrong error code. See bug 1307269.
@@ -589,30 +594,30 @@ TEST_F(TlsExtensionTest13Stream, Unknown
       wrong_group >> 8,
       wrong_group & 0xff,  // Group we didn't offer.
       0x00,
       0x02,  // length = 2
       0x01,
       0x02};
   DataBuffer buf(key_share, sizeof(key_share));
   EnsureTlsSetup();
-  server_->SetPacketFilter(
-      std::make_shared<TlsExtensionReplacer>(ssl_tls13_key_share_xtn, buf));
+  server_->SetFilter(std::make_shared<TlsExtensionReplacer>(
+      server_, ssl_tls13_key_share_xtn, buf));
   client_->ExpectSendAlert(kTlsAlertMissingExtension);
   server_->ExpectSendAlert(kTlsAlertBadRecordMac);
   ConnectExpectFail();
   EXPECT_EQ(SSL_ERROR_MISSING_KEY_SHARE, client_->error_code());
   EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code());
 }
 
 TEST_F(TlsExtensionTest13Stream, AddServerSignatureAlgorithmsOnResumption) {
   SetupForResume();
   DataBuffer empty;
-  server_->SetPacketFilter(std::make_shared<TlsExtensionInjector>(
-      ssl_signature_algorithms_xtn, empty));
+  server_->SetFilter(std::make_shared<TlsExtensionInjector>(
+      server_, ssl_signature_algorithms_xtn, empty));
   client_->ExpectSendAlert(kTlsAlertUnsupportedExtension);
   server_->ExpectSendAlert(kTlsAlertBadRecordMac);
   ConnectExpectFail();
   EXPECT_EQ(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, client_->error_code());
   EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code());
 }
 
 struct PskIdentity {
@@ -622,18 +627,22 @@ struct PskIdentity {
 
 class TlsPreSharedKeyReplacer;
 
 typedef std::function<void(TlsPreSharedKeyReplacer*)>
     TlsPreSharedKeyReplacerFunc;
 
 class TlsPreSharedKeyReplacer : public TlsExtensionFilter {
  public:
-  TlsPreSharedKeyReplacer(TlsPreSharedKeyReplacerFunc function)
-      : identities_(), binders_(), function_(function) {}
+  TlsPreSharedKeyReplacer(const std::shared_ptr<TlsAgent>& agent,
+                          TlsPreSharedKeyReplacerFunc function)
+      : TlsExtensionFilter(agent),
+        identities_(),
+        binders_(),
+        function_(function) {}
 
   static size_t CopyAndMaybeReplace(TlsParser* parser, size_t size,
                                     const std::unique_ptr<DataBuffer>& replace,
                                     size_t index, DataBuffer* output) {
     DataBuffer tmp;
     bool ret = parser->ReadVariable(&tmp, size);
     EXPECT_EQ(true, ret);
     if (!ret) return 0;
@@ -737,146 +746,151 @@ class TlsPreSharedKeyReplacer : public T
   }
 
   TlsPreSharedKeyReplacerFunc function_;
 };
 
 TEST_F(TlsExtensionTest13Stream, ResumeEmptyPskLabel) {
   SetupForResume();
 
-  client_->SetPacketFilter(std::make_shared<TlsPreSharedKeyReplacer>([](
-      TlsPreSharedKeyReplacer* r) { r->identities_[0].identity.Truncate(0); }));
+  client_->SetFilter(std::make_shared<TlsPreSharedKeyReplacer>(
+      client_, [](TlsPreSharedKeyReplacer* r) {
+        r->identities_[0].identity.Truncate(0);
+      }));
   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
   client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
   server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
 }
 
 // Flip the first byte of the binder.
 TEST_F(TlsExtensionTest13Stream, ResumeIncorrectBinderValue) {
   SetupForResume();
 
-  client_->SetPacketFilter(
-      std::make_shared<TlsPreSharedKeyReplacer>([](TlsPreSharedKeyReplacer* r) {
+  client_->SetFilter(std::make_shared<TlsPreSharedKeyReplacer>(
+      client_, [](TlsPreSharedKeyReplacer* r) {
         r->binders_[0].Write(0, r->binders_[0].data()[0] ^ 0xff, 1);
       }));
   ConnectExpectAlert(server_, kTlsAlertDecryptError);
   client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
   server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
 }
 
 // Extend the binder by one.
 TEST_F(TlsExtensionTest13Stream, ResumeIncorrectBinderLength) {
   SetupForResume();
 
-  client_->SetPacketFilter(
-      std::make_shared<TlsPreSharedKeyReplacer>([](TlsPreSharedKeyReplacer* r) {
+  client_->SetFilter(std::make_shared<TlsPreSharedKeyReplacer>(
+      client_, [](TlsPreSharedKeyReplacer* r) {
         r->binders_[0].Write(r->binders_[0].len(), 0xff, 1);
       }));
   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
   client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
   server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
 }
 
 // Binders must be at least 32 bytes.
 TEST_F(TlsExtensionTest13Stream, ResumeBinderTooShort) {
   SetupForResume();
 
-  client_->SetPacketFilter(std::make_shared<TlsPreSharedKeyReplacer>(
+  client_->SetFilter(std::make_shared<TlsPreSharedKeyReplacer>(
+      client_,
       [](TlsPreSharedKeyReplacer* r) { r->binders_[0].Truncate(31); }));
   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
   client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
   server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
 }
 
 // Duplicate the identity and binder. This will fail with an error
 // processing the binder (because we extended the identity list.)
 TEST_F(TlsExtensionTest13Stream, ResumeTwoPsks) {
   SetupForResume();
 
-  client_->SetPacketFilter(
-      std::make_shared<TlsPreSharedKeyReplacer>([](TlsPreSharedKeyReplacer* r) {
+  client_->SetFilter(std::make_shared<TlsPreSharedKeyReplacer>(
+      client_, [](TlsPreSharedKeyReplacer* r) {
         r->identities_.push_back(r->identities_[0]);
         r->binders_.push_back(r->binders_[0]);
       }));
   ConnectExpectAlert(server_, kTlsAlertDecryptError);
   client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
   server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
 }
 
 // The next two tests have mismatches in the number of identities
 // and binders. This generates an illegal parameter alert.
 TEST_F(TlsExtensionTest13Stream, ResumeTwoIdentitiesOneBinder) {
   SetupForResume();
 
-  client_->SetPacketFilter(
-      std::make_shared<TlsPreSharedKeyReplacer>([](TlsPreSharedKeyReplacer* r) {
+  client_->SetFilter(std::make_shared<TlsPreSharedKeyReplacer>(
+      client_, [](TlsPreSharedKeyReplacer* r) {
         r->identities_.push_back(r->identities_[0]);
       }));
   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
   client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
   server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
 }
 
 TEST_F(TlsExtensionTest13Stream, ResumeOneIdentityTwoBinders) {
   SetupForResume();
 
-  client_->SetPacketFilter(std::make_shared<TlsPreSharedKeyReplacer>([](
-      TlsPreSharedKeyReplacer* r) { r->binders_.push_back(r->binders_[0]); }));
+  client_->SetFilter(std::make_shared<TlsPreSharedKeyReplacer>(
+      client_, [](TlsPreSharedKeyReplacer* r) {
+        r->binders_.push_back(r->binders_[0]);
+      }));
   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
   client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
   server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
 }
 
 TEST_F(TlsExtensionTest13Stream, ResumePskExtensionNotLast) {
   SetupForResume();
 
   const uint8_t empty_buf[] = {0};
   DataBuffer empty(empty_buf, 0);
   // Inject an unused extension after the PSK extension.
-  client_->SetPacketFilter(std::make_shared<TlsExtensionAppender>(
-      kTlsHandshakeClientHello, 0xffff, empty));
+  client_->SetFilter(std::make_shared<TlsExtensionAppender>(
+      client_, kTlsHandshakeClientHello, 0xffff, empty));
   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
   client_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
   server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
 }
 
 TEST_F(TlsExtensionTest13Stream, ResumeNoKeModes) {
   SetupForResume();
 
   DataBuffer empty;
-  client_->SetPacketFilter(std::make_shared<TlsExtensionDropper>(
-      ssl_tls13_psk_key_exchange_modes_xtn));
+  client_->SetFilter(std::make_shared<TlsExtensionDropper>(
+      client_, ssl_tls13_psk_key_exchange_modes_xtn));
   ConnectExpectAlert(server_, kTlsAlertMissingExtension);
   client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT);
   server_->CheckErrorCode(SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES);
 }
 
 // The following test contains valid but unacceptable PreSharedKey
 // modes and therefore produces non-resumption followed by MAC
 // errors.
 TEST_F(TlsExtensionTest13Stream, ResumeBogusKeModes) {
   SetupForResume();
   const static uint8_t ke_modes[] = {1,  // Length
                                      kTls13PskKe};
 
   DataBuffer modes(ke_modes, sizeof(ke_modes));
-  client_->SetPacketFilter(std::make_shared<TlsExtensionReplacer>(
-      ssl_tls13_psk_key_exchange_modes_xtn, modes));
+  client_->SetFilter(std::make_shared<TlsExtensionReplacer>(
+      client_, ssl_tls13_psk_key_exchange_modes_xtn, modes));
   client_->ExpectSendAlert(kTlsAlertBadRecordMac);
   server_->ExpectSendAlert(kTlsAlertBadRecordMac);
   ConnectExpectFail();
   client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
   server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
 }
 
 TEST_P(TlsExtensionTest13, NoKeModesIfResumptionOff) {
   ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
   auto capture = std::make_shared<TlsExtensionCapture>(
-      ssl_tls13_psk_key_exchange_modes_xtn);
-  client_->SetPacketFilter(capture);
+      client_, ssl_tls13_psk_key_exchange_modes_xtn);
+  client_->SetFilter(capture);
   Connect();
   EXPECT_FALSE(capture->captured());
 }
 
 // In these tests, we downgrade to TLS 1.2, causing the
 // server to negotiate TLS 1.2.
 // 1. Both sides only support TLS 1.3, so we get a cipher version
 //    error.
@@ -961,22 +975,21 @@ class TlsBogusExtensionTest : public Tls
       : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {}
 
  protected:
   virtual void ConnectAndFail(uint8_t message) = 0;
 
   void AddFilter(uint8_t message, uint16_t extension) {
     static uint8_t empty_buf[1] = {0};
     DataBuffer empty(empty_buf, 0);
-    auto filter =
-        std::make_shared<TlsExtensionAppender>(message, extension, empty);
+    auto filter = std::make_shared<TlsExtensionAppender>(server_, message,
+                                                         extension, empty);
+    server_->SetFilter(filter);
     if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
-      server_->SetTlsRecordFilter(filter);
-    } else {
-      server_->SetPacketFilter(filter);
+      filter->EnableDecryption();
     }
   }
 
   void Run(uint8_t message, uint16_t extension = 0xff) {
     EnsureTlsSetup();
     AddFilter(message, extension);
     ConnectAndFail(message);
   }
@@ -1082,18 +1095,19 @@ TEST_P(TlsConnectStream, IncludePadding)
   // short enough not to push a TLS 1.3 ClientHello over 511.
   static const char* long_name =
       "chickenchickenchickenchickenchickenchickenchickenchicken."
       "chickenchickenchickenchickenchickenchickenchickenchicken."
       "chickenchickenchickenchickenchicken.";
   SECStatus rv = SSL_SetURL(client_->ssl_fd(), long_name);
   EXPECT_EQ(SECSuccess, rv);
 
-  auto capture = std::make_shared<TlsExtensionCapture>(ssl_padding_xtn);
-  client_->SetPacketFilter(capture);
+  auto capture =
+      std::make_shared<TlsExtensionCapture>(client_, ssl_padding_xtn);
+  client_->SetFilter(capture);
   client_->StartConnect();
   client_->Handshake();
   EXPECT_TRUE(capture->captured());
 }
 
 INSTANTIATE_TEST_CASE_P(
     ExtensionStream, TlsExtensionTestGeneric,
     ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
--- a/gtests/ssl_gtest/ssl_fragment_unittest.cc
+++ b/gtests/ssl_gtest/ssl_fragment_unittest.cc
@@ -144,20 +144,20 @@ class RecordFragmenter : public PacketFi
   }
 
  private:
   uint64_t sequence_number_;
   bool splitting_;
 };
 
 TEST_P(TlsConnectDatagram, FragmentClientPackets) {
-  client_->SetPacketFilter(std::make_shared<RecordFragmenter>());
+  client_->SetFilter(std::make_shared<RecordFragmenter>());
   Connect();
   SendReceive();
 }
 
 TEST_P(TlsConnectDatagram, FragmentServerPackets) {
-  server_->SetPacketFilter(std::make_shared<RecordFragmenter>());
+  server_->SetFilter(std::make_shared<RecordFragmenter>());
   Connect();
   SendReceive();
 }
 
 }  // namespace nss_test
--- a/gtests/ssl_gtest/ssl_fuzz_unittest.cc
+++ b/gtests/ssl_gtest/ssl_fuzz_unittest.cc
@@ -22,17 +22,18 @@ namespace nss_test {
 const uint8_t kShortEmptyFinished[8] = {0};
 const uint8_t kLongEmptyFinished[128] = {0};
 
 class TlsFuzzTest : public ::testing::Test {};
 
 // Record the application data stream.
 class TlsApplicationDataRecorder : public TlsRecordFilter {
  public:
-  TlsApplicationDataRecorder() : buffer_() {}
+  TlsApplicationDataRecorder(const std::shared_ptr<TlsAgent>& agent)
+      : TlsRecordFilter(agent), buffer_() {}
 
   virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                             const DataBuffer& input,
                                             DataBuffer* output) {
     if (header.content_type() == kTlsApplicationDataType) {
       buffer_.Append(input);
     }
 
@@ -101,26 +102,28 @@ FUZZ_P(TlsConnectGeneric, DeterministicT
   // Connect a few times and compare the transcripts byte-by-byte.
   DataBuffer last;
   for (size_t i = 0; i < 5; i++) {
     Reset();
     ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
     DisableECDHEServerKeyReuse();
 
     DataBuffer buffer;
-    client_->SetPacketFilter(std::make_shared<TlsConversationRecorder>(buffer));
-    server_->SetPacketFilter(std::make_shared<TlsConversationRecorder>(buffer));
+    client_->SetFilter(
+        std::make_shared<TlsConversationRecorder>(client_, buffer));
+    server_->SetFilter(
+        std::make_shared<TlsConversationRecorder>(server_, buffer));
 
     // Reset the RNG state.
     EXPECT_EQ(SECSuccess, RNG_RandomUpdate(NULL, 0));
     Connect();
 
     // Ensure the filters go away before |buffer| does.
-    client_->DeletePacketFilter();
-    server_->DeletePacketFilter();
+    client_->ClearFilter();
+    server_->ClearFilter();
 
     if (last.len() > 0) {
       EXPECT_EQ(last, buffer);
     }
 
     last = buffer;
   }
 }
@@ -128,20 +131,20 @@ FUZZ_P(TlsConnectGeneric, DeterministicT
 // Check that we can establish and use a connection
 // with all supported TLS versions, STREAM and DGRAM.
 // Check that records are NOT encrypted.
 // Check that records don't have a MAC.
 FUZZ_P(TlsConnectGeneric, ConnectSendReceive_NullCipher) {
   EnsureTlsSetup();
 
   // Set up app data filters.
-  auto client_recorder = std::make_shared<TlsApplicationDataRecorder>();
-  client_->SetPacketFilter(client_recorder);
-  auto server_recorder = std::make_shared<TlsApplicationDataRecorder>();
-  server_->SetPacketFilter(server_recorder);
+  auto client_recorder = std::make_shared<TlsApplicationDataRecorder>(client_);
+  client_->SetFilter(client_recorder);
+  auto server_recorder = std::make_shared<TlsApplicationDataRecorder>(server_);
+  server_->SetFilter(server_recorder);
 
   Connect();
 
   // Construct the plaintext.
   DataBuffer buf;
   buf.Allocate(50);
   for (size_t i = 0; i < buf.len(); ++i) {
     buf.data()[i] = i & 0xff;
@@ -156,54 +159,54 @@ FUZZ_P(TlsConnectGeneric, ConnectSendRec
   EXPECT_EQ(buf, client_recorder->buffer());
   EXPECT_EQ(buf, server_recorder->buffer());
 }
 
 // Check that an invalid Finished message doesn't abort the connection.
 FUZZ_P(TlsConnectGeneric, BogusClientFinished) {
   EnsureTlsSetup();
 
-  auto i1 = std::make_shared<TlsInspectorReplaceHandshakeMessage>(
-      kTlsHandshakeFinished,
+  auto filter = std::make_shared<TlsInspectorReplaceHandshakeMessage>(
+      client_, kTlsHandshakeFinished,
       DataBuffer(kShortEmptyFinished, sizeof(kShortEmptyFinished)));
-  client_->SetPacketFilter(i1);
+  client_->SetFilter(filter);
   Connect();
   SendReceive();
 }
 
 // Check that an invalid Finished message doesn't abort the connection.
 FUZZ_P(TlsConnectGeneric, BogusServerFinished) {
   EnsureTlsSetup();
 
-  auto i1 = std::make_shared<TlsInspectorReplaceHandshakeMessage>(
-      kTlsHandshakeFinished,
+  auto filter = std::make_shared<TlsInspectorReplaceHandshakeMessage>(
+      server_, kTlsHandshakeFinished,
       DataBuffer(kLongEmptyFinished, sizeof(kLongEmptyFinished)));
-  server_->SetPacketFilter(i1);
+  server_->SetFilter(filter);
   Connect();
   SendReceive();
 }
 
 // Check that an invalid server auth signature doesn't abort the connection.
 FUZZ_P(TlsConnectGeneric, BogusServerAuthSignature) {
   EnsureTlsSetup();
   uint8_t msg_type = version_ == SSL_LIBRARY_VERSION_TLS_1_3
                          ? kTlsHandshakeCertificateVerify
                          : kTlsHandshakeServerKeyExchange;
-  server_->SetPacketFilter(std::make_shared<TlsLastByteDamager>(msg_type));
+  server_->SetFilter(std::make_shared<TlsLastByteDamager>(server_, msg_type));
   Connect();
   SendReceive();
 }
 
 // Check that an invalid client auth signature doesn't abort the connection.
 FUZZ_P(TlsConnectGeneric, BogusClientAuthSignature) {
   EnsureTlsSetup();
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
-  client_->SetPacketFilter(
-      std::make_shared<TlsLastByteDamager>(kTlsHandshakeCertificateVerify));
+  client_->SetFilter(std::make_shared<TlsLastByteDamager>(
+      client_, kTlsHandshakeCertificateVerify));
   Connect();
 }
 
 // Check that session ticket resumption works.
 FUZZ_P(TlsConnectGeneric, SessionTicketResumption) {
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   Connect();
   SendReceive();
@@ -214,34 +217,34 @@ FUZZ_P(TlsConnectGeneric, SessionTicketR
   Connect();
   SendReceive();
 }
 
 // Check that session tickets are not encrypted.
 FUZZ_P(TlsConnectGeneric, UnencryptedSessionTickets) {
   ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET);
 
-  auto i1 = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      kTlsHandshakeNewSessionTicket);
-  server_->SetPacketFilter(i1);
+  auto filter = std::make_shared<TlsHandshakeRecorder>(
+      server_, kTlsHandshakeNewSessionTicket);
+  server_->SetFilter(filter);
   Connect();
 
-  std::cerr << "ticket" << i1->buffer() << std::endl;
+  std::cerr << "ticket" << filter->buffer() << std::endl;
   size_t offset = 4; /* lifetime */
   if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) {
     offset += 4; /* ticket_age_add */
     uint32_t nonce_len = 0;
-    EXPECT_TRUE(i1->buffer().Read(offset, 1, &nonce_len));
+    EXPECT_TRUE(filter->buffer().Read(offset, 1, &nonce_len));
     offset += 1 + nonce_len;
   }
   offset += 2 + /* ticket length */
             2;  /* TLS_EX_SESS_TICKET_VERSION */
   // Check the protocol version number.
   uint32_t tls_version = 0;
-  EXPECT_TRUE(i1->buffer().Read(offset, sizeof(version_), &tls_version));
+  EXPECT_TRUE(filter->buffer().Read(offset, sizeof(version_), &tls_version));
   EXPECT_EQ(version_, static_cast<decltype(version_)>(tls_version));
 
   // Check the cipher suite.
   uint32_t suite = 0;
-  EXPECT_TRUE(i1->buffer().Read(offset + sizeof(version_), 2, &suite));
+  EXPECT_TRUE(filter->buffer().Read(offset + sizeof(version_), 2, &suite));
   client_->CheckCipherSuite(static_cast<uint16_t>(suite));
 }
 }
--- a/gtests/ssl_gtest/ssl_hrr_unittest.cc
+++ b/gtests/ssl_gtest/ssl_hrr_unittest.cc
@@ -30,52 +30,56 @@ TEST_P(TlsConnectTls13, HelloRetryReques
                                                     ssl_grp_ec_secp521r1};
   server_->ConfigNamedGroups(groups);
   client_->Set0RttEnabled(true);
   server_->Set0RttEnabled(true);
   ExpectResumption(RESUME_TICKET);
 
   // Send first ClientHello and send 0-RTT data
   auto capture_early_data =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_early_data_xtn);
-  client_->SetPacketFilter(capture_early_data);
+      std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_early_data_xtn);
+  client_->SetFilter(capture_early_data);
   client_->Handshake();
   EXPECT_EQ(k0RttDataLen, PR_Write(client_->ssl_fd(), k0RttData,
                                    k0RttDataLen));  // 0-RTT write.
   EXPECT_TRUE(capture_early_data->captured());
 
   // Send the HelloRetryRequest
-  auto hrr_capture = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      kTlsHandshakeHelloRetryRequest);
-  server_->SetPacketFilter(hrr_capture);
+  auto hrr_capture = std::make_shared<TlsHandshakeRecorder>(
+      server_, kTlsHandshakeHelloRetryRequest);
+  server_->SetFilter(hrr_capture);
   server_->Handshake();
   EXPECT_LT(0U, hrr_capture->buffer().len());
 
   // The server can't read
   std::vector<uint8_t> buf(k0RttDataLen);
   EXPECT_EQ(SECFailure, PR_Read(server_->ssl_fd(), buf.data(), k0RttDataLen));
   EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
 
   // Make a new capture for the early data.
   capture_early_data =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_early_data_xtn);
-  client_->SetPacketFilter(capture_early_data);
+      std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_early_data_xtn);
+  client_->SetFilter(capture_early_data);
 
   // Complete the handshake successfully
   Handshake();
   ExpectEarlyDataAccepted(false);  // The server should reject 0-RTT
   CheckConnected();
   SendReceive();
   EXPECT_FALSE(capture_early_data->captured());
 }
 
 // This filter only works for DTLS 1.3 where there is exactly one handshake
 // packet. If the record is split into two packets, or there are multiple
 // handshake packets, this will break.
 class CorrectMessageSeqAfterHrrFilter : public TlsRecordFilter {
+ public:
+  CorrectMessageSeqAfterHrrFilter(const std::shared_ptr<TlsAgent>& agent)
+      : TlsRecordFilter(agent) {}
+
  protected:
   PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                     const DataBuffer& record, size_t* offset,
                                     DataBuffer* output) {
     if (filtered_packets() > 0 || header.content_type() != content_handshake) {
       return KEEP;
     }
 
@@ -126,18 +130,18 @@ TEST_P(TlsConnectTls13, SecondClientHell
   // Swap the client we created manually with the one that successfully
   // received a PSK, and try to resume with 0-RTT. The client doesn't know
   // about the HRR so it will send the early_data xtn as well as 0-RTT data.
   client_.swap(orig_client);
   orig_client.reset();
 
   // Correct the DTLS message sequence number after an HRR.
   if (variant_ == ssl_variant_datagram) {
-    client_->SetPacketFilter(
-        std::make_shared<CorrectMessageSeqAfterHrrFilter>());
+    client_->SetFilter(
+        std::make_shared<CorrectMessageSeqAfterHrrFilter>(client_));
   }
 
   server_->SetPeer(client_);
   client_->Handshake();
 
   // Send 0-RTT data.
   const char* k0RttData = "ABCDEF";
   const PRInt32 k0RttDataLen = static_cast<PRInt32>(strlen(k0RttData));
@@ -146,17 +150,18 @@ TEST_P(TlsConnectTls13, SecondClientHell
 
   ExpectAlert(server_, kTlsAlertUnsupportedExtension);
   Handshake();
   client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT);
 }
 
 class KeyShareReplayer : public TlsExtensionFilter {
  public:
-  KeyShareReplayer() {}
+  KeyShareReplayer(const std::shared_ptr<TlsAgent>& agent)
+      : TlsExtensionFilter(agent) {}
 
   virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
                                                const DataBuffer& input,
                                                DataBuffer* output) {
     if (extension_type != ssl_tls13_key_share_xtn) {
       return KEEP;
     }
 
@@ -173,31 +178,31 @@ class KeyShareReplayer : public TlsExten
   DataBuffer data_;
 };
 
 // This forces a HelloRetryRequest by disabling P-256 on the server.  However,
 // the second ClientHello is modified so that it omits the requested share.  The
 // server should reject this.
 TEST_P(TlsConnectTls13, RetryWithSameKeyShare) {
   EnsureTlsSetup();
-  client_->SetPacketFilter(std::make_shared<KeyShareReplayer>());
+  client_->SetFilter(std::make_shared<KeyShareReplayer>(client_));
   static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1,
                                                     ssl_grp_ec_secp521r1};
   server_->ConfigNamedGroups(groups);
   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
   EXPECT_EQ(SSL_ERROR_BAD_2ND_CLIENT_HELLO, server_->error_code());
   EXPECT_EQ(SSL_ERROR_ILLEGAL_PARAMETER_ALERT, client_->error_code());
 }
 
 // Here we modify the second ClientHello so that the client retries with the
 // same shares, even though the server wanted something else.
 TEST_P(TlsConnectTls13, RetryWithTwoShares) {
   EnsureTlsSetup();
   EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
-  client_->SetPacketFilter(std::make_shared<KeyShareReplayer>());
+  client_->SetFilter(std::make_shared<KeyShareReplayer>(client_));
 
   static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1,
                                                     ssl_grp_ec_secp521r1};
   server_->ConfigNamedGroups(groups);
   ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
   EXPECT_EQ(SSL_ERROR_BAD_2ND_CLIENT_HELLO, server_->error_code());
   EXPECT_EQ(SSL_ERROR_ILLEGAL_PARAMETER_ALERT, client_->error_code());
 }
@@ -233,19 +238,20 @@ TEST_P(TlsConnectTls13, RetryCallbackAcc
                                unsigned int appTokenMax, void* arg) {
     auto* called = reinterpret_cast<size_t*>(arg);
     ++*called;
 
     EXPECT_EQ(0U, clientTokenLen);
     return ssl_hello_retry_accept;
   };
 
-  auto capture = std::make_shared<TlsExtensionCapture>(ssl_tls13_cookie_xtn);
+  auto capture =
+      std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_cookie_xtn);
   capture->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
-  server_->SetPacketFilter(capture);
+  server_->SetFilter(capture);
 
   static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
   server_->ConfigNamedGroups(groups);
 
   size_t cb_run = 0;
   EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(
                             server_->ssl_fd(), accept_hello_twice, &cb_run));
   Connect();
@@ -354,42 +360,42 @@ SSLHelloRetryRequestAction RetryHello(PR
 
   EXPECT_EQ(0U, clientTokenLen);
   return firstHello ? ssl_hello_retry_request : ssl_hello_retry_accept;
 }
 
 TEST_P(TlsConnectTls13, RetryCallbackRetry) {
   EnsureTlsSetup();
 
-  auto capture_hrr = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      ssl_hs_hello_retry_request);
+  auto capture_hrr = std::make_shared<TlsHandshakeRecorder>(
+      server_, ssl_hs_hello_retry_request);
   auto capture_key_share =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
+      std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn);
   capture_key_share->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
   std::vector<std::shared_ptr<PacketFilter>> chain = {capture_hrr,
                                                       capture_key_share};
-  server_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(chain));
+  server_->SetFilter(std::make_shared<ChainedPacketFilter>(chain));
 
   size_t cb_called = 0;
   EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(),
                                                       RetryHello, &cb_called));
 
   // Do the first message exchange.
   StartConnect();
   client_->Handshake();
   server_->Handshake();
 
   EXPECT_EQ(1U, cb_called) << "callback should be called once here";
   EXPECT_LT(0U, capture_hrr->buffer().len()) << "HelloRetryRequest expected";
   EXPECT_FALSE(capture_key_share->captured())
       << "no key_share extension expected";
 
   auto capture_cookie =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_cookie_xtn);
-  client_->SetPacketFilter(capture_cookie);
+      std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_cookie_xtn);
+  client_->SetFilter(capture_cookie);
 
   Handshake();
   CheckConnected();
   EXPECT_EQ(2U, cb_called);
   EXPECT_TRUE(capture_cookie->captured()) << "should have a cookie";
 }
 
 static size_t CountShares(const DataBuffer& key_share) {
@@ -408,58 +414,58 @@ static size_t CountShares(const DataBuff
   return count;
 }
 
 TEST_P(TlsConnectTls13, RetryCallbackRetryWithAdditionalShares) {
   EnsureTlsSetup();
   EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
 
   auto capture_server =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
+      std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn);
   capture_server->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
-  server_->SetPacketFilter(capture_server);
+  server_->SetFilter(capture_server);
 
   size_t cb_called = 0;
   EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(),
                                                       RetryHello, &cb_called));
 
   // Do the first message exchange.
   StartConnect();
   client_->Handshake();
   server_->Handshake();
 
   EXPECT_EQ(1U, cb_called) << "callback should be called once here";
   EXPECT_FALSE(capture_server->captured())
       << "no key_share extension expected from server";
 
   auto capture_client_2nd =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
-  client_->SetPacketFilter(capture_client_2nd);
+      std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
+  client_->SetFilter(capture_client_2nd);
 
   Handshake();
   CheckConnected();
   EXPECT_EQ(2U, cb_called);
   EXPECT_TRUE(capture_client_2nd->captured()) << "client should send key_share";
   EXPECT_EQ(2U, CountShares(capture_client_2nd->extension()))
       << "client should still send two shares";
 }
 
 // The callback should be run even if we have another reason to send
 // HelloRetryRequest.  In this case, the server sends HRR because the server
 // wants a P-384 key share and the client didn't offer one.
 TEST_P(TlsConnectTls13, RetryCallbackRetryWithGroupMismatch) {
   EnsureTlsSetup();
 
   auto capture_cookie =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_cookie_xtn);
+      std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_cookie_xtn);
   capture_cookie->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
   auto capture_key_share =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
+      std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn);
   capture_key_share->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
-  server_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(
+  server_->SetFilter(std::make_shared<ChainedPacketFilter>(
       ChainedPacketFilterInit{capture_cookie, capture_key_share}));
 
   static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
   server_->ConfigNamedGroups(groups);
 
   size_t cb_called = 0;
   EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(),
                                                       RetryHello, &cb_called));
@@ -488,19 +494,19 @@ SSLHelloRetryRequestAction RetryHelloWit
             DataBuffer(clientToken, static_cast<size_t>(clientTokenLen)));
   return ssl_hello_retry_accept;
 }
 
 TEST_P(TlsConnectTls13, RetryCallbackRetryWithToken) {
   EnsureTlsSetup();
 
   auto capture_key_share =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
+      std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn);
   capture_key_share->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
-  server_->SetPacketFilter(capture_key_share);
+  server_->SetFilter(capture_key_share);
 
   size_t cb_called = 0;
   EXPECT_EQ(SECSuccess,
             SSL_HelloRetryRequestCallback(server_->ssl_fd(),
                                           RetryHelloWithToken, &cb_called));
   Connect();
   EXPECT_EQ(2U, cb_called);
   EXPECT_FALSE(capture_key_share->captured()) << "no key share expected";
@@ -508,19 +514,19 @@ TEST_P(TlsConnectTls13, RetryCallbackRet
 
 TEST_P(TlsConnectTls13, RetryCallbackRetryWithTokenAndGroupMismatch) {
   EnsureTlsSetup();
 
   static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
   server_->ConfigNamedGroups(groups);
 
   auto capture_key_share =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
+      std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn);
   capture_key_share->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
-  server_->SetPacketFilter(capture_key_share);
+  server_->SetFilter(capture_key_share);
 
   size_t cb_called = 0;
   EXPECT_EQ(SECSuccess,
             SSL_HelloRetryRequestCallback(server_->ssl_fd(),
                                           RetryHelloWithToken, &cb_called));
   Connect();
   EXPECT_EQ(2U, cb_called);
   EXPECT_TRUE(capture_key_share->captured()) << "key share expected";
@@ -584,32 +590,33 @@ TEST_P(TlsConnectTls13, RetryStateless) 
   SendReceive();
 }
 
 TEST_P(TlsConnectTls13, RetryStatefulDropCookie) {
   ConfigureSelfEncrypt();
   EnsureTlsSetup();
 
   TriggerHelloRetryRequest(client_, server_);
-  client_->SetPacketFilter(
-      std::make_shared<TlsExtensionDropper>(ssl_tls13_cookie_xtn));
+  client_->SetFilter(
+      std::make_shared<TlsExtensionDropper>(client_, ssl_tls13_cookie_xtn));
 
   ExpectAlert(server_, kTlsAlertMissingExtension);
   Handshake();
   client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT);
   server_->CheckErrorCode(SSL_ERROR_MISSING_COOKIE_EXTENSION);
 }
 
 // Stream only because DTLS drops bad packets.
 TEST_F(TlsConnectStreamTls13, RetryStatelessDamageFirstClientHello) {
   ConfigureSelfEncrypt();
   EnsureTlsSetup();
 
-  auto damage_ch = std::make_shared<TlsExtensionInjector>(0xfff3, DataBuffer());
-  client_->SetPacketFilter(damage_ch);
+  auto damage_ch =
+      std::make_shared<TlsExtensionInjector>(client_, 0xfff3, DataBuffer());
+  client_->SetFilter(damage_ch);
 
   TriggerHelloRetryRequest(client_, server_);
   MakeNewServer();
 
   // Key exchange fails when the handshake continues because client and server
   // disagree about the transcript.
   client_->ExpectSendAlert(kTlsAlertBadRecordMac);
   server_->ExpectSendAlert(kTlsAlertBadRecordMac);
@@ -620,51 +627,52 @@ TEST_F(TlsConnectStreamTls13, RetryState
 
 TEST_F(TlsConnectStreamTls13, RetryStatelessDamageSecondClientHello) {
   ConfigureSelfEncrypt();
   EnsureTlsSetup();
 
   TriggerHelloRetryRequest(client_, server_);
   MakeNewServer();
 
-  auto damage_ch = std::make_shared<TlsExtensionInjector>(0xfff3, DataBuffer());
-  client_->SetPacketFilter(damage_ch);
+  auto damage_ch =
+      std::make_shared<TlsExtensionInjector>(client_, 0xfff3, DataBuffer());
+  client_->SetFilter(damage_ch);
 
   // Key exchange fails when the handshake continues because client and server
   // disagree about the transcript.
   client_->ExpectSendAlert(kTlsAlertBadRecordMac);
   server_->ExpectSendAlert(kTlsAlertBadRecordMac);
   Handshake();
   server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
   client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
 }
 
 // Read the cipher suite from the HRR and disable it on the identified agent.
 static void DisableSuiteFromHrr(
     std::shared_ptr<TlsAgent>& agent,
-    std::shared_ptr<TlsInspectorRecordHandshakeMessage>& capture_hrr) {
+    std::shared_ptr<TlsHandshakeRecorder>& capture_hrr) {
   uint32_t tmp;
   size_t offset = 2 + 32;  // skip version + server_random
   ASSERT_TRUE(
       capture_hrr->buffer().Read(offset, 1, &tmp));  // session_id length
   EXPECT_EQ(0U, tmp);
   offset += 1 + tmp;
   ASSERT_TRUE(capture_hrr->buffer().Read(offset, 2, &tmp));  // suite
   EXPECT_EQ(
       SECSuccess,
       SSL_CipherPrefSet(agent->ssl_fd(), static_cast<uint16_t>(tmp), PR_FALSE));
 }
 
 TEST_P(TlsConnectTls13, RetryStatelessDisableSuiteClient) {
   ConfigureSelfEncrypt();
   EnsureTlsSetup();
 
-  auto capture_hrr = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      ssl_hs_hello_retry_request);
-  server_->SetPacketFilter(capture_hrr);
+  auto capture_hrr = std::make_shared<TlsHandshakeRecorder>(
+      server_, ssl_hs_hello_retry_request);
+  server_->SetFilter(capture_hrr);
 
   TriggerHelloRetryRequest(client_, server_);
   MakeNewServer();
 
   DisableSuiteFromHrr(client_, capture_hrr);
 
   // The client thinks that the HelloRetryRequest is bad, even though its
   // because it changed its mind about the cipher suite.
@@ -673,19 +681,19 @@ TEST_P(TlsConnectTls13, RetryStatelessDi
   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
 }
 
 TEST_P(TlsConnectTls13, RetryStatelessDisableSuiteServer) {
   ConfigureSelfEncrypt();
   EnsureTlsSetup();
 
-  auto capture_hrr = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      ssl_hs_hello_retry_request);
-  server_->SetPacketFilter(capture_hrr);
+  auto capture_hrr = std::make_shared<TlsHandshakeRecorder>(
+      server_, ssl_hs_hello_retry_request);
+  server_->SetFilter(capture_hrr);
 
   TriggerHelloRetryRequest(client_, server_);
   MakeNewServer();
 
   DisableSuiteFromHrr(server_, capture_hrr);
 
   ExpectAlert(server_, kTlsAlertIllegalParameter);
   Handshake();
@@ -756,33 +764,33 @@ TEST_P(TlsConnectTls13, RetryStatelessBa
 
 // Stream because the server doesn't consume the alert and terminate.
 TEST_F(TlsConnectStreamTls13, RetryWithDifferentCipherSuite) {
   EnsureTlsSetup();
   // Force a HelloRetryRequest.
   static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
   server_->ConfigNamedGroups(groups);
   // Then switch out the default suite (TLS_AES_128_GCM_SHA256).
-  server_->SetPacketFilter(std::make_shared<SelectedCipherSuiteReplacer>(
-      TLS_CHACHA20_POLY1305_SHA256));
+  server_->SetFilter(std::make_shared<SelectedCipherSuiteReplacer>(
+      server_, TLS_CHACHA20_POLY1305_SHA256));
 
   client_->ExpectSendAlert(kTlsAlertIllegalParameter);
   server_->ExpectSendAlert(kTlsAlertBadRecordMac);
   ConnectExpectFail();
   EXPECT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code());
   EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code());
 }
 
 // This tests that the second attempt at sending a ClientHello (after receiving
 // a HelloRetryRequest) is correctly retransmitted.
 TEST_F(TlsConnectDatagram13, DropClientSecondFlightWithHelloRetry) {
   static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1,
                                                     ssl_grp_ec_secp521r1};
   server_->ConfigNamedGroups(groups);
-  server_->SetPacketFilter(std::make_shared<SelectiveDropFilter>(0x2));
+  server_->SetFilter(std::make_shared<SelectiveDropFilter>(0x2));
   Connect();
 }
 
 class TlsKeyExchange13 : public TlsKeyExchangeTest {};
 
 // This should work, with an HRR, because the server prefers x25519 and the
 // client generates a share for P-384 on the initial ClientHello.
 TEST_P(TlsKeyExchange13, ConnectEcdhePreferenceMismatchHrr) {
@@ -828,19 +836,19 @@ TEST_P(TlsKeyExchange13,
       ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1, ssl_grp_ec_curve25519};
   client_->ConfigNamedGroups(client_groups);
   static const std::vector<SSLNamedGroup> server_groups = {
       ssl_grp_ec_curve25519};
   server_->ConfigNamedGroups(server_groups);
   EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
 
   auto capture_server =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
+      std::make_shared<TlsExtensionCapture>(server_, ssl_tls13_key_share_xtn);
   capture_server->SetHandshakeTypes({kTlsHandshakeHelloRetryRequest});
-  server_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(
+  server_->SetFilter(std::make_shared<ChainedPacketFilter>(
       ChainedPacketFilterInit{capture_hrr_, capture_server}));
 
   size_t cb_called = 0;
   EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(),
                                                       RetryHello, &cb_called));
 
   // Do the first message exchange.
   StartConnect();
--- a/gtests/ssl_gtest/ssl_keylog_unittest.cc
+++ b/gtests/ssl_gtest/ssl_keylog_unittest.cc
@@ -15,18 +15,18 @@
 
 namespace nss_test {
 
 static const std::string keylog_file_path = "keylog.txt";
 static const std::string keylog_env = "SSLKEYLOGFILE=" + keylog_file_path;
 
 class KeyLogFileTest : public TlsConnectGeneric {
  public:
-  void SetUp() {
-    TlsConnectTestBase::SetUp();
+  void SetUp() override {
+    TlsConnectGeneric::SetUp();
     // Remove previous results (if any).
     (void)remove(keylog_file_path.c_str());
     PR_SetEnv(keylog_env.c_str());
   }
 
   void CheckKeyLog() {
     std::ifstream f(keylog_file_path);
     std::map<std::string, size_t> labels;
--- a/gtests/ssl_gtest/ssl_loopback_unittest.cc
+++ b/gtests/ssl_gtest/ssl_loopback_unittest.cc
@@ -51,17 +51,18 @@ TEST_P(TlsConnectGeneric, CipherSuiteMis
   }
   ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
   client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
   server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
 }
 
 class TlsAlertRecorder : public TlsRecordFilter {
  public:
-  TlsAlertRecorder() : level_(255), description_(255) {}
+  TlsAlertRecorder(const std::shared_ptr<TlsAgent>& agent)
+      : TlsRecordFilter(agent), level_(255), description_(255) {}
 
   PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                     const DataBuffer& input,
                                     DataBuffer* output) override {
     if (level_ != 255) {  // Already captured.
       return KEEP;
     }
     if (header.content_type() != kTlsAlertType) {
@@ -81,53 +82,53 @@ class TlsAlertRecorder : public TlsRecor
 
  private:
   uint8_t level_;
   uint8_t description_;
 };
 
 class HelloTruncator : public TlsHandshakeFilter {
  public:
-  HelloTruncator()
+  HelloTruncator(const std::shared_ptr<TlsAgent>& agent)
       : TlsHandshakeFilter(
-            {kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {}
+            agent, {kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {}
   PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                        const DataBuffer& input,
                                        DataBuffer* output) override {
     output->Assign(input.data(), input.len() - 1);
     return CHANGE;
   }
 };
 
 // Verify that when NSS reports that an alert is sent, it is actually sent.
 TEST_P(TlsConnectGeneric, CaptureAlertServer) {
-  client_->SetPacketFilter(std::make_shared<HelloTruncator>());
-  auto alert_recorder = std::make_shared<TlsAlertRecorder>();
-  server_->SetPacketFilter(alert_recorder);
+  client_->SetFilter(std::make_shared<HelloTruncator>(client_));
+  auto alert_recorder = std::make_shared<TlsAlertRecorder>(server_);
+  server_->SetFilter(alert_recorder);
 
   ConnectExpectAlert(server_, kTlsAlertDecodeError);
   EXPECT_EQ(kTlsAlertFatal, alert_recorder->level());
   EXPECT_EQ(kTlsAlertDecodeError, alert_recorder->description());
 }
 
 TEST_P(TlsConnectGenericPre13, CaptureAlertClient) {
-  server_->SetPacketFilter(std::make_shared<HelloTruncator>());
-  auto alert_recorder = std::make_shared<TlsAlertRecorder>();
-  client_->SetPacketFilter(alert_recorder);
+  server_->SetFilter(std::make_shared<HelloTruncator>(server_));
+  auto alert_recorder = std::make_shared<TlsAlertRecorder>(client_);
+  client_->SetFilter(alert_recorder);
 
   ConnectExpectAlert(client_, kTlsAlertDecodeError);
   EXPECT_EQ(kTlsAlertFatal, alert_recorder->level());
   EXPECT_EQ(kTlsAlertDecodeError, alert_recorder->description());
 }
 
 // In TLS 1.3, the server can't read the client alert.
 TEST_P(TlsConnectTls13, CaptureAlertClient) {
-  server_->SetPacketFilter(std::make_shared<HelloTruncator>());
-  auto alert_recorder = std::make_shared<TlsAlertRecorder>();
-  client_->SetPacketFilter(alert_recorder);
+  server_->SetFilter(std::make_shared<HelloTruncator>(server_));
+  auto alert_recorder = std::make_shared<TlsAlertRecorder>(client_);
+  client_->SetFilter(alert_recorder);
 
   StartConnect();
 
   client_->Handshake();
   client_->ExpectSendAlert(kTlsAlertDecodeError);
   server_->Handshake();
   client_->Handshake();
   if (variant_ == ssl_variant_stream) {
@@ -168,17 +169,18 @@ TEST_P(TlsConnectDatagram, ConnectSrtp) 
 
 TEST_P(TlsConnectGeneric, ConnectSendReceive) {
   Connect();
   SendReceive();
 }
 
 class SaveTlsRecord : public TlsRecordFilter {
  public:
-  SaveTlsRecord(size_t index) : index_(index), count_(0), contents_() {}
+  SaveTlsRecord(const std::shared_ptr<TlsAgent>& agent, size_t index)
+      : TlsRecordFilter(agent), index_(index), count_(0), contents_() {}
 
   const DataBuffer& contents() const { return contents_; }
 
  protected:
   PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                     const DataBuffer& data,
                                     DataBuffer* changed) override {
     if (count_++ == index_) {
@@ -193,47 +195,50 @@ class SaveTlsRecord : public TlsRecordFi
   DataBuffer contents_;
 };
 
 // Check that decrypting filters work and can read any record.
 // This test (currently) only works in TLS 1.3 where we can decrypt.
 TEST_F(TlsConnectStreamTls13, DecryptRecordClient) {
   EnsureTlsSetup();
   // 0 = ClientHello, 1 = Finished, 2 = SendReceive, 3 = SendBuffer
-  auto saved = std::make_shared<SaveTlsRecord>(3);
-  client_->SetTlsRecordFilter(saved);
+  auto saved = std::make_shared<SaveTlsRecord>(client_, 3);
+  saved->EnableDecryption();
+  client_->SetFilter(saved);
   Connect();
   SendReceive();
 
   static const uint8_t data[] = {0xde, 0xad, 0xdc};
   DataBuffer buf(data, sizeof(data));
   client_->SendBuffer(buf);
   EXPECT_EQ(buf, saved->contents());
 }
 
 TEST_F(TlsConnectStreamTls13, DecryptRecordServer) {
   EnsureTlsSetup();
   // Disable tickets so that we are sure to not get NewSessionTicket.
   EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(),
                                       SSL_ENABLE_SESSION_TICKETS, PR_FALSE));
   // 0 = ServerHello, 1 = other handshake, 2 = SendReceive, 3 = SendBuffer
-  auto saved = std::make_shared<SaveTlsRecord>(3);
-  server_->SetTlsRecordFilter(saved);
+  auto saved = std::make_shared<SaveTlsRecord>(server_, 3);
+  saved->EnableDecryption();
+  server_->SetFilter(saved);
   Connect();
   SendReceive();
 
   static const uint8_t data[] = {0xde, 0xad, 0xd5};
   DataBuffer buf(data, sizeof(data));
   server_->SendBuffer(buf);
   EXPECT_EQ(buf, saved->contents());
 }
 
 class DropTlsRecord : public TlsRecordFilter {
  public:
-  DropTlsRecord(size_t index) : index_(index), count_(0) {}
+  DropTlsRecord(const std::shared_ptr<TlsAgent>& agent, size_t index)
+      : TlsRecordFilter(agent), index_(index), count_(0) {}
 
  protected:
   PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                     const DataBuffer& data,
                                     DataBuffer* changed) override {
     if (count_++ == index_) {
       return DROP;
     }
@@ -248,27 +253,31 @@ class DropTlsRecord : public TlsRecordFi
 // Test that decrypting filters work correctly and are able to drop records.
 TEST_F(TlsConnectStreamTls13, DropRecordServer) {
   EnsureTlsSetup();
   // Disable session tickets so that the server doesn't send an extra record.
   EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(),
                                       SSL_ENABLE_SESSION_TICKETS, PR_FALSE));
 
   // 0 = ServerHello, 1 = other handshake, 2 = first write
-  server_->SetTlsRecordFilter(std::make_shared<DropTlsRecord>(2));
+  auto filter = std::make_shared<DropTlsRecord>(server_, 2);
+  filter->EnableDecryption();
+  server_->SetFilter(filter);
   Connect();
   server_->SendData(23, 23);  // This should be dropped, so it won't be counted.
   server_->ResetSentBytes();
   SendReceive();
 }
 
 TEST_F(TlsConnectStreamTls13, DropRecordClient) {
   EnsureTlsSetup();
   // 0 = ClientHello, 1 = Finished, 2 = first write
-  client_->SetTlsRecordFilter(std::make_shared<DropTlsRecord>(2));
+  auto filter = std::make_shared<DropTlsRecord>(client_, 2);
+  filter->EnableDecryption();
+  client_->SetFilter(filter);
   Connect();
   client_->SendData(26, 26);  // This should be dropped, so it won't be counted.
   client_->ResetSentBytes();
   SendReceive();
 }
 
 // The next two tests takes advantage of the fact that we
 // automatically read the first 1024 bytes, so if
@@ -366,41 +375,42 @@ TEST_P(TlsHolddownTest, TestDtlsHolddown
   RunAllTimersDown();
   SendReceive();
   // One for send, one for receive.
   EXPECT_EQ(2, SSLInt_CountCipherSpecs(client_->ssl_fd()));
 }
 
 class TlsPreCCSHeaderInjector : public TlsRecordFilter {
  public:
-  TlsPreCCSHeaderInjector() {}
+  TlsPreCCSHeaderInjector(const std::shared_ptr<TlsAgent>& agent)
+      : TlsRecordFilter(agent) {}
   virtual PacketFilter::Action FilterRecord(
       const TlsRecordHeader& record_header, const DataBuffer& input,
       size_t* offset, DataBuffer* output) override {
     if (record_header.content_type() != kTlsChangeCipherSpecType) return KEEP;
 
     std::cerr << "Injecting Finished header before CCS\n";
     const uint8_t hhdr[] = {kTlsHandshakeFinished, 0x00, 0x00, 0x0c};
     DataBuffer hhdr_buf(hhdr, sizeof(hhdr));
     TlsRecordHeader nhdr(record_header.version(), kTlsHandshakeType, 0);
     *offset = nhdr.Write(output, *offset, hhdr_buf);
     *offset = record_header.Write(output, *offset, input);
     return CHANGE;
   }
 };
 
 TEST_P(TlsConnectStreamPre13, ClientFinishedHeaderBeforeCCS) {
-  client_->SetPacketFilter(std::make_shared<TlsPreCCSHeaderInjector>());
+  client_->SetFilter(std::make_shared<TlsPreCCSHeaderInjector>(client_));
   ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage);
   client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
   server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
 }
 
 TEST_P(TlsConnectStreamPre13, ServerFinishedHeaderBeforeCCS) {
-  server_->SetPacketFilter(std::make_shared<TlsPreCCSHeaderInjector>());
+  server_->SetFilter(std::make_shared<TlsPreCCSHeaderInjector>(server_));
   StartConnect();
   ExpectAlert(client_, kTlsAlertUnexpectedMessage);
   Handshake();
   EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
   client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
   EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
   server_->Handshake();  // Make sure alert is consumed.
 }
@@ -471,18 +481,18 @@ static size_t ExpectedCbcLen(size_t in, 
   // MAC-then-Encrypt expansion formula:
   return ((in + hmac + (block - 1)) / block) * block;
 }
 
 TEST_F(TlsConnectTest, OneNRecordSplitting) {
   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_0);
   EnsureTlsSetup();
   ConnectWithCipherSuite(TLS_RSA_WITH_AES_128_CBC_SHA);
-  auto records = std::make_shared<TlsRecordRecorder>();
-  server_->SetPacketFilter(records);
+  auto records = std::make_shared<TlsRecordRecorder>(server_);
+  server_->SetFilter(records);
   // This should be split into 1, 16384 and 20.
   DataBuffer big_buffer;
   big_buffer.Allocate(1 + 16384 + 20);
   server_->SendBuffer(big_buffer);
   ASSERT_EQ(3U, records->count());
   EXPECT_EQ(ExpectedCbcLen(1), records->record(0).buffer.len());
   EXPECT_EQ(ExpectedCbcLen(16384), records->record(1).buffer.len());
   EXPECT_EQ(ExpectedCbcLen(20), records->record(2).buffer.len());
--- a/gtests/ssl_gtest/ssl_record_unittest.cc
+++ b/gtests/ssl_gtest/ssl_record_unittest.cc
@@ -98,18 +98,18 @@ TEST_P(TlsPaddingTest, LastByteOfPadWron
     plaintext_.Write(plaintext_.len() - 2,
                      plaintext_.data()[plaintext_.len() - 1] + 1, 1);
     Unpad(false);
   }
 }
 
 class RecordReplacer : public TlsRecordFilter {
  public:
-  RecordReplacer(size_t size)
-      : TlsRecordFilter(), enabled_(false), size_(size) {}
+  RecordReplacer(const std::shared_ptr<TlsAgent>& agent, size_t size)
+      : TlsRecordFilter(agent), enabled_(false), size_(size) {}
 
   PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                     const DataBuffer& data,
                                     DataBuffer* changed) override {
     if (!enabled_) {
       return KEEP;
     }
 
@@ -130,32 +130,34 @@ class RecordReplacer : public TlsRecordF
   bool enabled_;
   size_t size_;
 };
 
 TEST_F(TlsConnectStreamTls13, LargeRecord) {
   EnsureTlsSetup();
 
   const size_t record_limit = 16384;
-  auto replacer = std::make_shared<RecordReplacer>(record_limit);
-  client_->SetTlsRecordFilter(replacer);
+  auto replacer = std::make_shared<RecordReplacer>(client_, record_limit);
+  replacer->EnableDecryption();
+  client_->SetFilter(replacer);
   Connect();
 
   replacer->Enable();
   client_->SendData(10);
   WAIT_(server_->received_bytes() == record_limit, 2000);
   ASSERT_EQ(record_limit, server_->received_bytes());
 }
 
 TEST_F(TlsConnectStreamTls13, TooLargeRecord) {
   EnsureTlsSetup();
 
   const size_t record_limit = 16384;
-  auto replacer = std::make_shared<RecordReplacer>(record_limit + 1);
-  client_->SetTlsRecordFilter(replacer);
+  auto replacer = std::make_shared<RecordReplacer>(client_, record_limit + 1);
+  replacer->EnableDecryption();
+  client_->SetFilter(replacer);
   Connect();
 
   replacer->Enable();
   ExpectAlert(server_, kTlsAlertRecordOverflow);
   client_->SendData(10);  // This is expanded.
 
   uint8_t buf[record_limit + 2];
   PRInt32 rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf));
@@ -172,9 +174,9 @@ const static size_t kContentSizesArr[] =
     1, kMacSize - 1, kMacSize, 30, 31, 32, 36, 256, 257, 287, 288};
 
 auto kContentSizes = ::testing::ValuesIn(kContentSizesArr);
 const static bool kTrueFalseArr[] = {true, false};
 auto kTrueFalse = ::testing::ValuesIn(kTrueFalseArr);
 
 INSTANTIATE_TEST_CASE_P(TlsPadding, TlsPaddingTest,
                         ::testing::Combine(kContentSizes, kTrueFalse));
-}  // namespace nspr_test
+}  // namespace nss_test
--- a/gtests/ssl_gtest/ssl_resumption_unittest.cc
+++ b/gtests/ssl_gtest/ssl_resumption_unittest.cc
@@ -214,18 +214,18 @@ TEST_P(TlsConnectGenericResumption, Conn
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ExpectResumption(RESUME_NONE);
 
   // TLS 1.3 uses the pre-shared key extension instead.
   SSLExtensionType xtn = (version_ >= SSL_LIBRARY_VERSION_TLS_1_3)
                              ? ssl_tls13_pre_shared_key_xtn
                              : ssl_session_ticket_xtn;
-  auto capture = std::make_shared<TlsExtensionCapture>(xtn);
-  client_->SetPacketFilter(capture);
+  auto capture = std::make_shared<TlsExtensionCapture>(client_, xtn);
+  client_->SetFilter(capture);
   Connect();
 
   if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
     EXPECT_FALSE(capture->captured());
   } else {
     EXPECT_TRUE(capture->captured());
     EXPECT_EQ(0U, capture->extension().len());
   }
@@ -240,18 +240,18 @@ TEST_P(TlsConnectGeneric, ConnectWithExp
 
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ExpectResumption(RESUME_NONE);
 
   SSLExtensionType xtn = (version_ >= SSL_LIBRARY_VERSION_TLS_1_3)
                              ? ssl_tls13_pre_shared_key_xtn
                              : ssl_session_ticket_xtn;
-  auto capture = std::make_shared<TlsExtensionCapture>(xtn);
-  client_->SetPacketFilter(capture);
+  auto capture = std::make_shared<TlsExtensionCapture>(client_, xtn);
+  client_->SetFilter(capture);
   StartConnect();
   client_->Handshake();
   EXPECT_TRUE(capture->captured());
   EXPECT_LT(0U, capture->extension().len());
 
   WAIT_(false, 1000);  // Let the ticket expire on the server.
 
   Handshake();
@@ -322,65 +322,65 @@ TEST_P(TlsConnectGeneric, ServerSNICertT
   Connect();
   ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
   CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
   EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
 }
 
 // Prior to TLS 1.3, we were not fully ephemeral; though 1.3 fixes that
 TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceReuseKey) {
-  auto i1 = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      kTlsHandshakeServerKeyExchange);
-  server_->SetPacketFilter(i1);
+  auto filter = std::make_shared<TlsHandshakeRecorder>(
+      server_, kTlsHandshakeServerKeyExchange);
+  server_->SetFilter(filter);
   Connect();
   CheckKeys();
   TlsServerKeyExchangeEcdhe dhe1;
-  EXPECT_TRUE(dhe1.Parse(i1->buffer()));
+  EXPECT_TRUE(dhe1.Parse(filter->buffer()));
 
   // Restart
   Reset();
-  auto i2 = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      kTlsHandshakeServerKeyExchange);
-  server_->SetPacketFilter(i2);
+  auto filter2 = std::make_shared<TlsHandshakeRecorder>(
+      server_, kTlsHandshakeServerKeyExchange);
+  server_->SetFilter(filter2);
   ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
   Connect();
   CheckKeys();
 
   TlsServerKeyExchangeEcdhe dhe2;
-  EXPECT_TRUE(dhe2.Parse(i2->buffer()));
+  EXPECT_TRUE(dhe2.Parse(filter2->buffer()));
 
   // Make sure they are the same.
   EXPECT_EQ(dhe1.public_key_.len(), dhe2.public_key_.len());
   EXPECT_TRUE(!memcmp(dhe1.public_key_.data(), dhe2.public_key_.data(),
                       dhe1.public_key_.len()));
 }
 
 // This test parses the ServerKeyExchange, which isn't in 1.3
 TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceNewKey) {
   server_->SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
-  auto i1 = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      kTlsHandshakeServerKeyExchange);
-  server_->SetPacketFilter(i1);
+  auto filter = std::make_shared<TlsHandshakeRecorder>(
+      server_, kTlsHandshakeServerKeyExchange);
+  server_->SetFilter(filter);
   Connect();
   CheckKeys();
   TlsServerKeyExchangeEcdhe dhe1;
-  EXPECT_TRUE(dhe1.Parse(i1->buffer()));
+  EXPECT_TRUE(dhe1.Parse(filter->buffer()));
 
   // Restart
   Reset();
   server_->SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
-  auto i2 = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      kTlsHandshakeServerKeyExchange);
-  server_->SetPacketFilter(i2);
+  auto filter2 = std::make_shared<TlsHandshakeRecorder>(
+      server_, kTlsHandshakeServerKeyExchange);
+  server_->SetFilter(filter2);
   ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
   Connect();
   CheckKeys();
 
   TlsServerKeyExchangeEcdhe dhe2;
-  EXPECT_TRUE(dhe2.Parse(i2->buffer()));
+  EXPECT_TRUE(dhe2.Parse(filter2->buffer()));
 
   // Make sure they are different.
   EXPECT_FALSE((dhe1.public_key_.len() == dhe2.public_key_.len()) &&
                (!memcmp(dhe1.public_key_.data(), dhe2.public_key_.data(),
                         dhe1.public_key_.len())));
 }
 
 // Verify that TLS 1.3 reports an accurate group on resumption.
@@ -429,18 +429,19 @@ TEST_P(TlsConnectGenericResumption, Test
   ExpectResumption(RESUME_NONE);
   client_->EnableSingleCipher(ChooseAnotherCipher(version_));
   uint16_t ticket_extension;
   if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
     ticket_extension = ssl_tls13_pre_shared_key_xtn;
   } else {
     ticket_extension = ssl_session_ticket_xtn;
   }
-  auto ticket_capture = std::make_shared<TlsExtensionCapture>(ticket_extension);
-  client_->SetPacketFilter(ticket_capture);
+  auto ticket_capture =
+      std::make_shared<TlsExtensionCapture>(client_, ticket_extension);
+  client_->SetFilter(ticket_capture);
   Connect();
   CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
   EXPECT_EQ(0U, ticket_capture->extension().len());
 }
 
 // Test that we don't resume when we can't negotiate the same cipher.
 TEST_P(TlsConnectGenericResumption, TestResumeServerDifferentCipher) {
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
@@ -463,18 +464,18 @@ TEST_P(TlsConnectStream, TestResumptionO
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   server_->EnableSingleCipher(ChooseOneCipher(version_));
   Connect();
   SendReceive();
   CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
 
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
-  server_->SetPacketFilter(std::make_shared<SelectedCipherSuiteReplacer>(
-      ChooseAnotherCipher(version_)));
+  server_->SetFilter(std::make_shared<SelectedCipherSuiteReplacer>(
+      server_, ChooseAnotherCipher(version_)));
 
   if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
     client_->ExpectSendAlert(kTlsAlertIllegalParameter);
     server_->ExpectSendAlert(kTlsAlertBadRecordMac);
   } else {
     ExpectAlert(client_, kTlsAlertHandshakeFailure);
   }
   ConnectExpectFail();
@@ -485,18 +486,20 @@ TEST_P(TlsConnectStream, TestResumptionO
     server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
   } else {
     server_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILURE_ALERT);
   }
 }
 
 class SelectedVersionReplacer : public TlsHandshakeFilter {
  public:
-  SelectedVersionReplacer(uint16_t version)
-      : TlsHandshakeFilter({kTlsHandshakeServerHello}), version_(version) {}
+  SelectedVersionReplacer(const std::shared_ptr<TlsAgent>& agent,
+                          uint16_t version)
+      : TlsHandshakeFilter(agent, {kTlsHandshakeServerHello}),
+        version_(version) {}
 
  protected:
   PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                        const DataBuffer& input,
                                        DataBuffer* output) override {
     *output = input;
     output->Write(0, static_cast<uint32_t>(version_), 2);
     return CHANGE;
@@ -538,18 +541,18 @@ TEST_P(TlsConnectGenericPre13, TestResum
   Connect();
   CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
 
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   // Enable the lower version on the client.
   client_->SetVersionRange(version_ - 1, version_);
   server_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
-  server_->SetPacketFilter(
-      std::make_shared<SelectedVersionReplacer>(override_version));
+  server_->SetFilter(
+      std::make_shared<SelectedVersionReplacer>(server_, override_version));
 
   ConnectExpectAlert(client_, kTlsAlertHandshakeFailure);
   client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
   server_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILURE_ALERT);
 }
 
 // Test that two TLS resumptions work and produce the same ticket.
 // This will change after bug 1257047 is fixed.
@@ -562,35 +565,37 @@ TEST_F(TlsConnectTest, TestTls13Resumpti
   CheckKeys();
   uint16_t original_suite;
   EXPECT_TRUE(client_->cipher_suite(&original_suite));
 
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
   ExpectResumption(RESUME_TICKET);
-  auto c1 = std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn);
-  client_->SetPacketFilter(c1);
+  auto c1 = std::make_shared<TlsExtensionCapture>(client_,
+                                                  ssl_tls13_pre_shared_key_xtn);
+  client_->SetFilter(c1);
   Connect();
   SendReceive();
   CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
             ssl_sig_rsa_pss_rsae_sha256);
   // The filter will go away when we reset, so save the captured extension.
   DataBuffer initialTicket(c1->extension());
   ASSERT_LT(0U, initialTicket.len());
 
   ScopedCERTCertificate cert1(SSL_PeerCertificate(client_->ssl_fd()));
   ASSERT_TRUE(!!cert1.get());
 
   Reset();
   ClearStats();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
-  auto c2 = std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn);
-  client_->SetPacketFilter(c2);
+  auto c2 = std::make_shared<TlsExtensionCapture>(client_,
+                                                  ssl_tls13_pre_shared_key_xtn);
+  client_->SetFilter(c2);
   ExpectResumption(RESUME_TICKET);
   Connect();
   SendReceive();
   CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
             ssl_sig_rsa_pss_rsae_sha256);
   ASSERT_LT(0U, c2->extension().len());
 
   ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
@@ -651,19 +656,20 @@ void NstTicketMatchesPskIdentity(const D
 
   EXPECT_EQ(nst_ticket, psk_ticket);
 }
 
 TEST_F(TlsConnectTest, TestTls13ResumptionDuplicateNSTWithToken) {
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
 
-  auto nst_capture = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      ssl_hs_new_session_ticket);
-  server_->SetTlsRecordFilter(nst_capture);
+  auto nst_capture = std::make_shared<TlsHandshakeRecorder>(
+      server_, ssl_hs_new_session_ticket);
+  nst_capture->EnableDecryption();
+  server_->SetFilter(nst_capture);
   Connect();
 
   // Clear the session ticket keys to invalidate the old ticket.
   SSLInt_ClearSelfEncryptKey();
   nst_capture->Reset();
   uint8_t token[] = {0x20, 0x20, 0xff, 0x00};
   EXPECT_EQ(SECSuccess,
             SSL_SendSessionTicket(server_->ssl_fd(), token, sizeof(token)));
@@ -673,55 +679,56 @@ TEST_F(TlsConnectTest, TestTls13Resumpti
   EXPECT_LT(0U, nst_capture->buffer().len());
 
   // Resume the connection.
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
   ExpectResumption(RESUME_TICKET);
 
-  auto psk_capture =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn);
-  client_->SetPacketFilter(psk_capture);
+  auto psk_capture = std::make_shared<TlsExtensionCapture>(
+      client_, ssl_tls13_pre_shared_key_xtn);
+  client_->SetFilter(psk_capture);
   Connect();
   SendReceive();
 
   NstTicketMatchesPskIdentity(nst_capture->buffer(), psk_capture->extension());
 }
 
 // Disable SSL_ENABLE_SESSION_TICKETS but ensure that tickets can still be sent
 // by invoking SSL_SendSessionTicket directly (and that the ticket is usable).
 TEST_F(TlsConnectTest, SendSessionTicketWithTicketsDisabled) {
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
 
   EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(),
                                       SSL_ENABLE_SESSION_TICKETS, PR_FALSE));
 
-  auto nst_capture = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      ssl_hs_new_session_ticket);
-  server_->SetTlsRecordFilter(nst_capture);
+  auto nst_capture = std::make_shared<TlsHandshakeRecorder>(
+      server_, ssl_hs_new_session_ticket);
+  nst_capture->EnableDecryption();
+  server_->SetFilter(nst_capture);
   Connect();
 
   EXPECT_EQ(0U, nst_capture->buffer().len()) << "expect nothing captured yet";
 
   EXPECT_EQ(SECSuccess, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0));
   EXPECT_LT(0U, nst_capture->buffer().len()) << "should capture now";
 
   SendReceive();  // Ensure that the client reads the ticket.
 
   // Resume the connection.
   Reset();
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
   ExpectResumption(RESUME_TICKET);
 
-  auto psk_capture =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_pre_shared_key_xtn);
-  client_->SetPacketFilter(psk_capture);
+  auto psk_capture = std::make_shared<TlsExtensionCapture>(
+      client_, ssl_tls13_pre_shared_key_xtn);
+  client_->SetFilter(psk_capture);
   Connect();
   SendReceive();
 
   NstTicketMatchesPskIdentity(nst_capture->buffer(), psk_capture->extension());
 }
 
 // Test calling SSL_SendSessionTicket in inappropriate conditions.
 TEST_F(TlsConnectTest, SendSessionTicketInappropriate) {
@@ -814,30 +821,30 @@ TEST_F(TlsConnectTest, TestTls13Resumpti
   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
                            SSL_LIBRARY_VERSION_TLS_1_3);
 
   // Add filters that set downgrade SH.version to 1.2 and the cipher suite
   // to one that works with 1.2, so that we don't run into early sanity checks.
   // We will eventually fail the (sid.version == SH.version) check.
   std::vector<std::shared_ptr<PacketFilter>> filters;
   filters.push_back(std::make_shared<SelectedCipherSuiteReplacer>(
-      TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256));
-  filters.push_back(
-      std::make_shared<SelectedVersionReplacer>(SSL_LIBRARY_VERSION_TLS_1_2));
+      server_, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256));
+  filters.push_back(std::make_shared<SelectedVersionReplacer>(
+      server_, SSL_LIBRARY_VERSION_TLS_1_2));
 
   // Drop a bunch of extensions so that we get past the SH processing.  The
   // version extension says TLS 1.3, which is counter to our goal, the others
   // are not permitted in TLS 1.2 handshakes.
-  filters.push_back(
-      std::make_shared<TlsExtensionDropper>(ssl_tls13_supported_versions_xtn));
+  filters.push_back(std::make_shared<TlsExtensionDropper>(
+      server_, ssl_tls13_supported_versions_xtn));
   filters.push_back(
-      std::make_shared<TlsExtensionDropper>(ssl_tls13_key_share_xtn));
-  filters.push_back(
-      std::make_shared<TlsExtensionDropper>(ssl_tls13_pre_shared_key_xtn));
-  server_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(filters));
+      std::make_shared<TlsExtensionDropper>(server_, ssl_tls13_key_share_xtn));
+  filters.push_back(std::make_shared<TlsExtensionDropper>(
+      server_, ssl_tls13_pre_shared_key_xtn));
+  server_->SetFilter(std::make_shared<ChainedPacketFilter>(filters));
 
   // The client here generates an unexpected_message alert when it receives an
   // encrypted handshake message from the server (EncryptedExtension).  The
   // client expects to receive an unencrypted TLS 1.2 Certificate message.
   // The server can't decrypt the alert.
   client_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
   server_->ExpectSendAlert(kTlsAlertBadRecordMac);  // Server can't read
   ConnectExpectFail();
--- a/gtests/ssl_gtest/ssl_skip_unittest.cc
+++ b/gtests/ssl_gtest/ssl_skip_unittest.cc
@@ -17,18 +17,21 @@
  * See <https://www.smacktls.com/smack.pdf> for a description of the problems
  * that this sort of attack can enable.
  */
 namespace nss_test {
 
 class TlsHandshakeSkipFilter : public TlsRecordFilter {
  public:
   // A TLS record filter that skips handshake messages of the identified type.
-  TlsHandshakeSkipFilter(uint8_t handshake_type)
-      : handshake_type_(handshake_type), skipped_(false) {}
+  TlsHandshakeSkipFilter(const std::shared_ptr<TlsAgent>& agent,
+                         uint8_t handshake_type)
+      : TlsRecordFilter(agent),
+        handshake_type_(handshake_type),
+        skipped_(false) {}
 
  protected:
   // Takes a record; if it is a handshake record, it removes the first handshake
   // message that is of handshake_type_ type.
   virtual PacketFilter::Action FilterRecord(
       const TlsRecordHeader& record_header, const DataBuffer& input,
       DataBuffer* output) {
     if (record_header.content_type() != kTlsHandshakeType) {
@@ -87,144 +90,155 @@ class TlsHandshakeSkipFilter : public Tl
 
 class TlsSkipTest : public TlsConnectTestBase,
                     public ::testing::WithParamInterface<
                         std::tuple<SSLProtocolVariant, uint16_t>> {
  protected:
   TlsSkipTest()
       : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {}
 
+  void SetUp() override {
+    TlsConnectTestBase::SetUp();
+    EnsureTlsSetup();
+  }
+
   void ServerSkipTest(std::shared_ptr<PacketFilter> filter,
                       uint8_t alert = kTlsAlertUnexpectedMessage) {
-    server_->SetPacketFilter(filter);
+    server_->SetFilter(filter);
     ConnectExpectAlert(client_, alert);
   }
 };
 
 class Tls13SkipTest : public TlsConnectTestBase,
                       public ::testing::WithParamInterface<SSLProtocolVariant> {
  protected:
   Tls13SkipTest()
       : TlsConnectTestBase(GetParam(), SSL_LIBRARY_VERSION_TLS_1_3) {}
 
-  void ServerSkipTest(std::shared_ptr<TlsRecordFilter> filter, int32_t error) {
+  void SetUp() override {
+    TlsConnectTestBase::SetUp();
     EnsureTlsSetup();
-    server_->SetTlsRecordFilter(filter);
+  }
+
+  void ServerSkipTest(std::shared_ptr<TlsRecordFilter> filter, int32_t error) {
+    filter->EnableDecryption();
+    server_->SetFilter(filter);
     ExpectAlert(client_, kTlsAlertUnexpectedMessage);
     ConnectExpectFail();
     client_->CheckErrorCode(error);
     server_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
   }
 
   void ClientSkipTest(std::shared_ptr<TlsRecordFilter> filter, int32_t error) {
-    EnsureTlsSetup();
-    client_->SetTlsRecordFilter(filter);
+    filter->EnableDecryption();
+    client_->SetFilter(filter);
     server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
     ConnectExpectFailOneSide(TlsAgent::SERVER);
 
     server_->CheckErrorCode(error);
     ASSERT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
 
     client_->Handshake();  // Make sure to consume the alert the server sends.
   }
 };
 
 TEST_P(TlsSkipTest, SkipCertificateRsa) {
   EnableOnlyStaticRsaCiphers();
-  ServerSkipTest(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate));
+  ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>(
+      server_, kTlsHandshakeCertificate));
   client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
 }
 
 TEST_P(TlsSkipTest, SkipCertificateDhe) {
-  ServerSkipTest(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate));
+  ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>(
+      server_, kTlsHandshakeCertificate));
   client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH);
 }
 
 TEST_P(TlsSkipTest, SkipCertificateEcdhe) {
-  ServerSkipTest(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate));
+  ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>(
+      server_, kTlsHandshakeCertificate));
   client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH);
 }
 
 TEST_P(TlsSkipTest, SkipCertificateEcdsa) {
   Reset(TlsAgent::kServerEcdsa256);
-  ServerSkipTest(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate));
+  ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>(
+      server_, kTlsHandshakeCertificate));
   client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH);
 }
 
 TEST_P(TlsSkipTest, SkipServerKeyExchange) {
-  ServerSkipTest(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeServerKeyExchange));
+  ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>(
+      server_, kTlsHandshakeServerKeyExchange));
   client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
 }
 
 TEST_P(TlsSkipTest, SkipServerKeyExchangeEcdsa) {
   Reset(TlsAgent::kServerEcdsa256);
-  ServerSkipTest(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeServerKeyExchange));
+  ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>(
+      server_, kTlsHandshakeServerKeyExchange));
   client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
 }
 
 TEST_P(TlsSkipTest, SkipCertAndKeyExch) {
-  auto chain = std::make_shared<ChainedPacketFilter>(ChainedPacketFilterInit{
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate),
-      std::make_shared<TlsHandshakeSkipFilter>(
-          kTlsHandshakeServerKeyExchange)});
+  auto chain = std::make_shared<ChainedPacketFilter>(
+      ChainedPacketFilterInit{std::make_shared<TlsHandshakeSkipFilter>(
+                                  server_, kTlsHandshakeCertificate),
+                              std::make_shared<TlsHandshakeSkipFilter>(
+                                  server_, kTlsHandshakeServerKeyExchange)});
   ServerSkipTest(chain);
   client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
 }
 
 TEST_P(TlsSkipTest, SkipCertAndKeyExchEcdsa) {
   Reset(TlsAgent::kServerEcdsa256);
   auto chain = std::make_shared<ChainedPacketFilter>();
-  chain->Add(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate));
-  chain->Add(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeServerKeyExchange));
+  chain->Add(std::make_shared<TlsHandshakeSkipFilter>(
+      server_, kTlsHandshakeCertificate));
+  chain->Add(std::make_shared<TlsHandshakeSkipFilter>(
+      server_, kTlsHandshakeServerKeyExchange));
   ServerSkipTest(chain);
   client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
 }
 
 TEST_P(Tls13SkipTest, SkipEncryptedExtensions) {
   ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>(
-                     kTlsHandshakeEncryptedExtensions),
+                     server_, kTlsHandshakeEncryptedExtensions),
                  SSL_ERROR_RX_UNEXPECTED_CERTIFICATE);
 }
 
 TEST_P(Tls13SkipTest, SkipServerCertificate) {
-  ServerSkipTest(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate),
-      SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY);
+  ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>(
+                     server_, kTlsHandshakeCertificate),
+                 SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY);
 }
 
 TEST_P(Tls13SkipTest, SkipServerCertificateVerify) {
-  ServerSkipTest(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificateVerify),
-      SSL_ERROR_RX_UNEXPECTED_FINISHED);
+  ServerSkipTest(std::make_shared<TlsHandshakeSkipFilter>(
+                     server_, kTlsHandshakeCertificateVerify),
+                 SSL_ERROR_RX_UNEXPECTED_FINISHED);
 }
 
 TEST_P(Tls13SkipTest, SkipClientCertificate) {
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   client_->ExpectReceiveAlert(kTlsAlertUnexpectedMessage);
-  ClientSkipTest(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificate),
-      SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY);
+  ClientSkipTest(std::make_shared<TlsHandshakeSkipFilter>(
+                     client_, kTlsHandshakeCertificate),
+                 SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY);
 }
 
 TEST_P(Tls13SkipTest, SkipClientCertificateVerify) {
   client_->SetupClientAuth();
   server_->RequestClientAuth(true);
   client_->ExpectReceiveAlert(kTlsAlertUnexpectedMessage);
-  ClientSkipTest(
-      std::make_shared<TlsHandshakeSkipFilter>(kTlsHandshakeCertificateVerify),
-      SSL_ERROR_RX_UNEXPECTED_FINISHED);
+  ClientSkipTest(std::make_shared<TlsHandshakeSkipFilter>(
+                     client_, kTlsHandshakeCertificateVerify),
+                 SSL_ERROR_RX_UNEXPECTED_FINISHED);
 }
 
 INSTANTIATE_TEST_CASE_P(
     SkipTls10, TlsSkipTest,
     ::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
                        TlsConnectTestBase::kTlsV10));
 INSTANTIATE_TEST_CASE_P(SkipVariants, TlsSkipTest,
                         ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
--- a/gtests/ssl_gtest/ssl_staticrsa_unittest.cc
+++ b/gtests/ssl_gtest/ssl_staticrsa_unittest.cc
@@ -43,67 +43,65 @@ TEST_P(TlsConnectGenericPre13, ConnectSt
   Connect();
   CheckKeys(ssl_kea_rsa, ssl_grp_none, ssl_auth_rsa_decrypt, ssl_sig_none);
 }
 
 // Test that a totally bogus EPMS is handled correctly.
 // This test is stream so we can catch the bad_record_mac alert.
 TEST_P(TlsConnectStreamPre13, ConnectStaticRSABogusCKE) {
   EnableOnlyStaticRsaCiphers();
-  auto i1 = std::make_shared<TlsInspectorReplaceHandshakeMessage>(
-      kTlsHandshakeClientKeyExchange,
-      DataBuffer(kBogusClientKeyExchange, sizeof(kBogusClientKeyExchange)));
-  client_->SetPacketFilter(i1);
+  client_->SetFilter(std::make_shared<TlsInspectorReplaceHandshakeMessage>(
+      client_, kTlsHandshakeClientKeyExchange,
+      DataBuffer(kBogusClientKeyExchange, sizeof(kBogusClientKeyExchange))));
   ConnectExpectAlert(server_, kTlsAlertBadRecordMac);
 }
 
 // Test that a PMS with a bogus version number is handled correctly.
 // This test is stream so we can catch the bad_record_mac alert.
 TEST_P(TlsConnectStreamPre13, ConnectStaticRSABogusPMSVersionDetect) {
   EnableOnlyStaticRsaCiphers();
-  client_->SetPacketFilter(
-      std::make_shared<TlsInspectorClientHelloVersionChanger>(server_));
+  client_->SetFilter(
+      std::make_shared<TlsClientHelloVersionChanger>(client_, server_));
   ConnectExpectAlert(server_, kTlsAlertBadRecordMac);
 }
 
 // Test that a PMS with a bogus version number is ignored when
 // rollback detection is disabled. This is a positive control for
 // ConnectStaticRSABogusPMSVersionDetect.
 TEST_P(TlsConnectGenericPre13, ConnectStaticRSABogusPMSVersionIgnore) {
   EnableOnlyStaticRsaCiphers();
-  client_->SetPacketFilter(
-      std::make_shared<TlsInspectorClientHelloVersionChanger>(server_));
+  client_->SetFilter(
+      std::make_shared<TlsClientHelloVersionChanger>(client_, server_));
   server_->SetOption(SSL_ROLLBACK_DETECTION, PR_FALSE);
   Connect();
 }
 
 // This test is stream so we can catch the bad_record_mac alert.
 TEST_P(TlsConnectStreamPre13, ConnectExtendedMasterSecretStaticRSABogusCKE) {
   EnableOnlyStaticRsaCiphers();
   EnableExtendedMasterSecret();
-  auto inspect = std::make_shared<TlsInspectorReplaceHandshakeMessage>(
-      kTlsHandshakeClientKeyExchange,
-      DataBuffer(kBogusClientKeyExchange, sizeof(kBogusClientKeyExchange)));
-  client_->SetPacketFilter(inspect);
+  client_->SetFilter(std::make_shared<TlsInspectorReplaceHandshakeMessage>(
+      client_, kTlsHandshakeClientKeyExchange,
+      DataBuffer(kBogusClientKeyExchange, sizeof(kBogusClientKeyExchange))));
   ConnectExpectAlert(server_, kTlsAlertBadRecordMac);
 }
 
 // This test is stream so we can catch the bad_record_mac alert.
 TEST_P(TlsConnectStreamPre13,
        ConnectExtendedMasterSecretStaticRSABogusPMSVersionDetect) {
   EnableOnlyStaticRsaCiphers();
   EnableExtendedMasterSecret();
-  client_->SetPacketFilter(
-      std::make_shared<TlsInspectorClientHelloVersionChanger>(server_));
+  client_->SetFilter(
+      std::make_shared<TlsClientHelloVersionChanger>(client_, server_));
   ConnectExpectAlert(server_, kTlsAlertBadRecordMac);
 }
 
 TEST_P(TlsConnectStreamPre13,
        ConnectExtendedMasterSecretStaticRSABogusPMSVersionIgnore) {
   EnableOnlyStaticRsaCiphers();
   EnableExtendedMasterSecret();
-  client_->SetPacketFilter(
-      std::make_shared<TlsInspectorClientHelloVersionChanger>(server_));
+  client_->SetFilter(
+      std::make_shared<TlsClientHelloVersionChanger>(client_, server_));
   server_->SetOption(SSL_ROLLBACK_DETECTION, PR_FALSE);
   Connect();
 }
 
-}  // namespace nspr_test
+}  // namespace nss_test
--- a/gtests/ssl_gtest/ssl_tls13compat_unittest.cc
+++ b/gtests/ssl_gtest/ssl_tls13compat_unittest.cc
@@ -62,20 +62,17 @@ class Tls13CompatTest : public TlsConnec
     CheckHelloVersions();
     EXPECT_EQ(32U, client_recorders_.session_id_length());
     EXPECT_EQ(32U, server_recorders_.session_id_length());
     CheckForCCS(true, true);
   }
 
  private:
   struct Recorders {
-    Recorders()
-        : records_(new TlsRecordRecorder()),
-          hello_(new TlsInspectorRecordHandshakeMessage(std::set<uint8_t>(
-              {kTlsHandshakeClientHello, kTlsHandshakeServerHello}))) {}
+    Recorders() : records_(nullptr), hello_(nullptr) {}
 
     uint8_t session_id_length() const {
       // session_id is always after version (2) and random (32).
       uint32_t len = 0;
       EXPECT_TRUE(hello_->buffer().Read(2 + 32, 1, &len));
       return static_cast<uint8_t>(len);
     }
 
@@ -86,22 +83,32 @@ class Tls13CompatTest : public TlsConnec
         bool expected_match = expected && (i == 1);
         EXPECT_EQ(expected_match,
                   kTlsChangeCipherSpecType ==
                       records_->record(i).header.content_type());
       }
     }
 
     void Install(std::shared_ptr<TlsAgent>& agent) {
-      agent->SetPacketFilter(std::make_shared<ChainedPacketFilter>(
+      if (records_ && records_->agent() == agent) {
+        // Avoid replacing the filters if they are already installed on this
+        // agent. This ensures that InstallFilters() can be used after
+        // MakeNewServer() without losing state on the client filters.
+        return;
+      }
+      records_.reset(new TlsRecordRecorder(agent));
+      hello_.reset(new TlsHandshakeRecorder(
+          agent, std::set<uint8_t>(
+                     {kTlsHandshakeClientHello, kTlsHandshakeServerHello})));
+      agent->SetFilter(std::make_shared<ChainedPacketFilter>(
           ChainedPacketFilterInit({records_, hello_})));
     }
 
     std::shared_ptr<TlsRecordRecorder> records_;
-    std::shared_ptr<TlsInspectorRecordHandshakeMessage> hello_;
+    std::shared_ptr<TlsHandshakeRecorder> hello_;
   };
 
   void CheckRecordsAreTls12(const std::string& agent,
                             const std::shared_ptr<TlsRecordRecorder>& records,
                             size_t start) {
     EXPECT_LE(start, records->count());
     for (size_t i = start; i < records->count(); ++i) {
       EXPECT_EQ(SSL_LIBRARY_VERSION_TLS_1_2,
@@ -166,26 +173,30 @@ TEST_F(Tls13CompatTest, EnabledStateless
   InstallFilters();
 
   // Force a HelloRetryRequest
   server_->ConfigNamedGroups({ssl_grp_ec_secp384r1});
   client_->StartConnect();
   server_->StartConnect();
   client_->Handshake();
   server_->Handshake();
+
+  // The server should send CCS before HRR.
   CheckForCCS(false, true);
 
-  // A new server should just work, but not send another CCS.
+  // A new server should complete the handshake, and not send CCS.
   MakeNewServer();
   InstallFilters();
   server_->ConfigNamedGroups({ssl_grp_ec_secp384r1});
 
   Handshake();
   CheckConnected();
-  CheckForCompatHandshake();
+  CheckRecordVersions();
+  CheckHelloVersions();
+  CheckForCCS(true, false);
 }
 
 TEST_F(Tls13CompatTest, EnabledHrrZeroRtt) {
   SetupForZeroRtt();
   EnableCompatMode();
   InstallFilters();
   server_->ConfigNamedGroups({ssl_grp_ec_secp384r1});
 
@@ -257,20 +268,20 @@ TEST_F(TlsConnectStreamTls13, ChangeCiph
   ConnectExpectAlert(server_, kTlsAlertUnexpectedMessage);
   server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
   client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
 }
 
 TEST_F(TlsConnectDatagram13, CompatModeDtlsClient) {
   EnsureTlsSetup();
   client_->SetOption(SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE);
-  auto client_records = std::make_shared<TlsRecordRecorder>();
-  client_->SetPacketFilter(client_records);
-  auto server_records = std::make_shared<TlsRecordRecorder>();
-  server_->SetPacketFilter(server_records);
+  auto client_records = std::make_shared<TlsRecordRecorder>(client_);
+  client_->SetFilter(client_records);
+  auto server_records = std::make_shared<TlsRecordRecorder>(server_);
+  server_->SetFilter(server_records);
   Connect();
 
   ASSERT_EQ(2U, client_records->count());  // CH, Fin
   EXPECT_EQ(kTlsHandshakeType, client_records->record(0).header.content_type());
   EXPECT_EQ(kTlsApplicationDataType,
             client_records->record(1).header.content_type());
 
   ASSERT_EQ(6U, server_records->count());  // SH, EE, CT, CV, Fin, Ack
@@ -278,17 +289,18 @@ TEST_F(TlsConnectDatagram13, CompatModeD
   for (size_t i = 1; i < server_records->count(); ++i) {
     EXPECT_EQ(kTlsApplicationDataType,
               server_records->record(i).header.content_type());
   }
 }
 
 class AddSessionIdFilter : public TlsHandshakeFilter {
  public:
-  AddSessionIdFilter() : TlsHandshakeFilter({ssl_hs_client_hello}) {}
+  AddSessionIdFilter(const std::shared_ptr<TlsAgent>& client)
+      : TlsHandshakeFilter(client, {ssl_hs_client_hello}) {}
 
  protected:
   PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                        const DataBuffer& input,
                                        DataBuffer* output) override {
     uint32_t session_id_len = 0;
     EXPECT_TRUE(input.Read(2 + 32, 1, &session_id_len));
     EXPECT_EQ(0U, session_id_len);
@@ -298,24 +310,24 @@ class AddSessionIdFilter : public TlsHan
     return CHANGE;
   }
 };
 
 // Adding a session ID to a DTLS ClientHello should not trigger compatibility
 // mode.  It should be ignored instead.
 TEST_F(TlsConnectDatagram13, CompatModeDtlsServer) {
   EnsureTlsSetup();
-  auto client_records = std::make_shared<TlsRecordRecorder>();
-  client_->SetPacketFilter(
+  auto client_records = std::make_shared<TlsRecordRecorder>(client_);
+  client_->SetFilter(
       std::make_shared<ChainedPacketFilter>(ChainedPacketFilterInit(
-          {client_records, std::make_shared<AddSessionIdFilter>()})));
-  auto server_hello = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      kTlsHandshakeServerHello);
-  auto server_records = std::make_shared<TlsRecordRecorder>();
-  server_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(
+          {client_records, std::make_shared<AddSessionIdFilter>(client_)})));
+  auto server_hello =
+      std::make_shared<TlsHandshakeRecorder>(server_, kTlsHandshakeServerHello);
+  auto server_records = std::make_shared<TlsRecordRecorder>(server_);
+  server_->SetFilter(std::make_shared<ChainedPacketFilter>(
       ChainedPacketFilterInit({server_records, server_hello})));
   StartConnect();
   client_->Handshake();
   server_->Handshake();
   // The client will consume the ServerHello, but discard everything else
   // because it doesn't decrypt.  And don't wait around for the client to ACK.
   client_->Handshake();
 
@@ -329,9 +341,9 @@ TEST_F(TlsConnectDatagram13, CompatModeD
               server_records->record(i).header.content_type());
   }
 
   uint32_t session_id_len = 0;
   EXPECT_TRUE(server_hello->buffer().Read(2 + 32, 1, &session_id_len));
   EXPECT_EQ(0U, session_id_len);
 }
 
-}  // nss_test
+}  // namespace nss_test
--- a/gtests/ssl_gtest/ssl_v2_client_hello_unittest.cc
+++ b/gtests/ssl_gtest/ssl_v2_client_hello_unittest.cc
@@ -142,20 +142,20 @@ class SSLv2ClientHelloFilter : public Pa
 class SSLv2ClientHelloTestF : public TlsConnectTestBase {
  public:
   SSLv2ClientHelloTestF()
       : TlsConnectTestBase(ssl_variant_stream, 0), filter_(nullptr) {}
 
   SSLv2ClientHelloTestF(SSLProtocolVariant variant, uint16_t version)
       : TlsConnectTestBase(variant, version), filter_(nullptr) {}
 
-  void SetUp() {
+  void SetUp() override {
     TlsConnectTestBase::SetUp();
     filter_ = std::make_shared<SSLv2ClientHelloFilter>(client_, version_);
-    client_->SetPacketFilter(filter_);
+    client_->SetFilter(filter_);
   }
 
   void SetExpectedVersion(uint16_t version) {
     TlsConnectTestBase::SetExpectedVersion(version);
     filter_->SetVersion(version);
   }
 
   void SetAvailableCipherSuite(uint16_t cipher) {
--- a/gtests/ssl_gtest/ssl_version_unittest.cc
+++ b/gtests/ssl_gtest/ssl_version_unittest.cc
@@ -51,55 +51,51 @@ TEST_P(TlsConnectGeneric, ServerNegotiat
 #ifndef TLS_1_3_DRAFT_VERSION
 
 // Test the ServerRandom version hack from
 // [draft-ietf-tls-tls13-11 Section 6.3.1.1].
 // The first three tests test for active tampering. The next
 // two validate that we can also detect fallback using the
 // SSL_SetDowngradeCheckVersion() API.
 TEST_F(TlsConnectTest, TestDowngradeDetectionToTls11) {
-  client_->SetPacketFilter(
-      std::make_shared<TlsInspectorClientHelloVersionSetter>(
-          SSL_LIBRARY_VERSION_TLS_1_1));
+  client_->SetFilter(std::make_shared<TlsClientHelloVersionSetter>(
+      client_, SSL_LIBRARY_VERSION_TLS_1_1));
   ConnectExpectFail();
   ASSERT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code());
 }
 
 /* Attempt to negotiate the bogus DTLS 1.1 version. */
 TEST_F(DtlsConnectTest, TestDtlsVersion11) {
-  client_->SetPacketFilter(
-      std::make_shared<TlsInspectorClientHelloVersionSetter>(
-          ((~0x0101) & 0xffff)));
+  client_->SetFilter(std::make_shared<TlsClientHelloVersionSetter>(
+      client_, ((~0x0101) & 0xffff)));
   ConnectExpectFail();
   // It's kind of surprising that SSL_ERROR_NO_CYPHER_OVERLAP is
   // what is returned here, but this is deliberate in ssl3_HandleAlert().
   EXPECT_EQ(SSL_ERROR_NO_CYPHER_OVERLAP, client_->error_code());
   EXPECT_EQ(SSL_ERROR_UNSUPPORTED_VERSION, server_->error_code());
 }
 
 // Disabled as long as we have draft version.
 TEST_F(TlsConnectTest, TestDowngradeDetectionToTls12) {
   EnsureTlsSetup();
-  client_->SetPacketFilter(
-      std::make_shared<TlsInspectorClientHelloVersionSetter>(
-          SSL_LIBRARY_VERSION_TLS_1_2));
+  client_->SetFilter(std::make_shared<TlsClientHelloVersionSetter>(
+      client_, SSL_LIBRARY_VERSION_TLS_1_2));
   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
                            SSL_LIBRARY_VERSION_TLS_1_3);
   ConnectExpectFail();
   ASSERT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code());
 }
 
 // TLS 1.1 clients do not check the random values, so we should
 // instead get a handshake failure alert from the server.
 TEST_F(TlsConnectTest, TestDowngradeDetectionToTls10) {
-  client_->SetPacketFilter(
-      std::make_shared<TlsInspectorClientHelloVersionSetter>(
-          SSL_LIBRARY_VERSION_TLS_1_0));
+  client_->SetFilter(std::make_shared<TlsClientHelloVersionSetter>(
+      client_, SSL_LIBRARY_VERSION_TLS_1_0));
   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
                            SSL_LIBRARY_VERSION_TLS_1_1);
   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
                            SSL_LIBRARY_VERSION_TLS_1_2);
   ConnectExpectFail();
   ASSERT_EQ(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE, server_->error_code());
   ASSERT_EQ(SSL_ERROR_DECRYPT_ERROR_ALERT, client_->error_code());
 }
@@ -172,22 +168,21 @@ TEST_P(TlsConnectGeneric, AlertBeforeSer
 }
 
 class Tls13NoSupportedVersions : public TlsConnectStreamTls12 {
  protected:
   void Run(uint16_t overwritten_client_version, uint16_t max_server_version) {
     client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
                              SSL_LIBRARY_VERSION_TLS_1_2);
     server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2, max_server_version);
-    client_->SetPacketFilter(
-        std::make_shared<TlsInspectorClientHelloVersionSetter>(
-            overwritten_client_version));
-    auto capture = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-        kTlsHandshakeServerHello);
-    server_->SetPacketFilter(capture);
+    client_->SetFilter(std::make_shared<TlsClientHelloVersionSetter>(
+        client_, overwritten_client_version));
+    auto capture = std::make_shared<TlsHandshakeRecorder>(
+        server_, kTlsHandshakeServerHello);
+    server_->SetFilter(capture);
     ConnectExpectAlert(server_, kTlsAlertDecryptError);
     client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
     server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
     const DataBuffer& server_hello = capture->buffer();
     ASSERT_GT(server_hello.len(), 2U);
     uint32_t ver;
     ASSERT_TRUE(server_hello.Read(0, 2, &ver));
     ASSERT_EQ(static_cast<uint32_t>(SSL_LIBRARY_VERSION_TLS_1_2), ver);
@@ -209,22 +204,21 @@ TEST_F(Tls13NoSupportedVersions,
 TEST_F(Tls13NoSupportedVersions,
        Tls14ClientHelloWithoutSupportedVersionsServer13) {
   Run(SSL_LIBRARY_VERSION_TLS_1_3 + 1, SSL_LIBRARY_VERSION_TLS_1_3);
 }
 
 // Offer 1.3 but with ClientHello.legacy_version == TLS 1.4. This
 // causes a bad MAC error when we read EncryptedExtensions.
 TEST_F(TlsConnectStreamTls13, Tls14ClientHelloWithSupportedVersions) {
-  client_->SetPacketFilter(
-      std::make_shared<TlsInspectorClientHelloVersionSetter>(
-          SSL_LIBRARY_VERSION_TLS_1_3 + 1));
-  auto capture =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_supported_versions_xtn);
-  server_->SetPacketFilter(capture);
+  client_->SetFilter(std::make_shared<TlsClientHelloVersionSetter>(
+      client_, SSL_LIBRARY_VERSION_TLS_1_3 + 1));
+  auto capture = std::make_shared<TlsExtensionCapture>(
+      server_, ssl_tls13_supported_versions_xtn);
+  server_->SetFilter(capture);
   client_->ExpectSendAlert(kTlsAlertBadRecordMac);
   server_->ExpectSendAlert(kTlsAlertBadRecordMac);
   ConnectExpectFail();
   client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
   server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
 
   ASSERT_EQ(2U, capture->extension().len());
   uint32_t version = 0;
--- a/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc
+++ b/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc
@@ -184,22 +184,22 @@ class TestPolicyVersionRange
                                  SSLVersionRange* r) {
     ASSERT_TRUE(r != nullptr);
     if (r->max >= SSL_LIBRARY_VERSION_TLS_1_3 &&
         r->min < SSL_LIBRARY_VERSION_TLS_1_0) {
       r->min = SSL_LIBRARY_VERSION_TLS_1_0;
     }
   }
 
-  void SetUp() {
+  void SetUp() override {
+    TlsConnectTestBase::SetUp();
     SetPolicy(policy_.range());
-    TlsConnectTestBase::SetUp();
   }
 
-  void TearDown() {
+  void TearDown() override {
     TlsConnectTestBase::TearDown();
     saved_version_policy_.RestoreOriginalPolicy();
   }
 
  protected:
   class VersionPolicy {
    public:
     VersionPolicy() { SaveOriginalPolicy(); }
--- a/gtests/ssl_gtest/test_io.cc
+++ b/gtests/ssl_gtest/test_io.cc
@@ -20,20 +20,16 @@ extern bool g_ssl_gtest_verbose;
 namespace nss_test {
 
 #define LOG(a) std::cerr << name_ << ": " << a << std::endl
 #define LOGV(a)                      \
   do {                               \
     if (g_ssl_gtest_verbose) LOG(a); \
   } while (false)
 
-void DummyPrSocket::SetPacketFilter(std::shared_ptr<PacketFilter> filter) {
-  filter_ = filter;
-}
-
 ScopedPRFileDesc DummyPrSocket::CreateFD() {
   static PRDescIdentity test_fd_identity =
       PR_GetUniqueIdentity("testtransportadapter");
   return DummyIOLayerMethods::CreateFD(test_fd_identity, this);
 }
 
 void DummyPrSocket::PacketReceived(const DataBuffer &packet) {
   input_.push(Packet(packet));
--- a/gtests/ssl_gtest/test_io.h
+++ b/gtests/ssl_gtest/test_io.h
@@ -69,17 +69,19 @@ class DummyPrSocket : public DummyIOLaye
   virtual ~DummyPrSocket() {}
 
   // Create a file descriptor that will reference this object.  The fd must not
   // live longer than this adapter; call PR_Close() before.
   ScopedPRFileDesc CreateFD();
 
   std::weak_ptr<DummyPrSocket>& peer() { return peer_; }
   void SetPeer(const std::shared_ptr<DummyPrSocket>& peer) { peer_ = peer; }
-  void SetPacketFilter(std::shared_ptr<PacketFilter> filter);
+  void SetPacketFilter(const std::shared_ptr<PacketFilter>& filter) {
+    filter_ = filter;
+  }
   // Drops peer, packet filter and any outstanding packets.
   void Reset();
 
   void PacketReceived(const DataBuffer& data);
   int32_t Read(PRFileDesc* f, void* data, int32_t len) override;
   int32_t Recv(PRFileDesc* f, void* buf, int32_t buflen, int32_t flags,
                PRIntervalTime to) override;
   int32_t Write(PRFileDesc* f, const void* buf, int32_t length) override;
@@ -171,11 +173,11 @@ class Poller {
 
   static Poller* instance;
   std::map<std::shared_ptr<DummyPrSocket>, std::unique_ptr<Waiter>> waiters_;
   std::priority_queue<std::shared_ptr<Timer>,
                       std::vector<std::shared_ptr<Timer>>, TimerComparator>
       timers_;
 };
 
-}  // end of namespace
+}  // namespace nss_test
 
 #endif
--- a/gtests/ssl_gtest/tls_agent.h
+++ b/gtests/ssl_gtest/tls_agent.h
@@ -75,28 +75,20 @@ class TlsAgent : public PollTarget {
 
   TlsAgent(const std::string& name, Role role, SSLProtocolVariant variant);
   virtual ~TlsAgent();
 
   void SetPeer(std::shared_ptr<TlsAgent>& peer) {
     adapter_->SetPeer(peer->adapter_);
   }
 
-  // Set a filter that can access plaintext (TLS 1.3 only).
-  void SetTlsRecordFilter(std::shared_ptr<TlsRecordFilter> filter) {
-    filter->SetAgent(this);
-    adapter_->SetPacketFilter(filter);
-    filter->EnableDecryption();
-  }
-
-  void SetPacketFilter(std::shared_ptr<PacketFilter> filter) {
+  void SetFilter(std::shared_ptr<PacketFilter> filter) {
     adapter_->SetPacketFilter(filter);
   }
-
-  void DeletePacketFilter() { adapter_->SetPacketFilter(nullptr); }
+  void ClearFilter() { adapter_->SetPacketFilter(nullptr); }
 
   void StartConnect(PRFileDesc* model = nullptr);
   void CheckKEA(SSLKEAType kea_type, SSLNamedGroup group,
                 size_t kea_size = 0) const;
   void CheckOriginalKEA(SSLNamedGroup kea_group) const;
   void CheckAuthType(SSLAuthType auth_type,
                      SSLSignatureScheme sig_scheme) const;
 
@@ -458,17 +450,17 @@ class TlsAgentTestBase : public ::testin
   void Init(const std::string& server_name = TlsAgent::kServerRsa);
   void Reset(const std::string& server_name = TlsAgent::kServerRsa);
 
  protected:
   void EnsureInit();
   void ProcessMessage(const DataBuffer& buffer, TlsAgent::State expected_state,
                       int32_t error_code = 0);
 
-  std::unique_ptr<TlsAgent> agent_;
+  std::shared_ptr<TlsAgent> agent_;
   TlsAgent::Role role_;
   SSLProtocolVariant variant_;
   uint16_t version_;
   // This adapter is here just to accept packets from this agent.
   std::shared_ptr<DummyPrSocket> sink_adapter_;
 };
 
 class TlsAgentTest
--- a/gtests/ssl_gtest/tls_connect.cc
+++ b/gtests/ssl_gtest/tls_connect.cc
@@ -765,27 +765,27 @@ TlsConnectTls13ResumptionToken::TlsConne
     : TlsConnectTestBase(GetParam(), SSL_LIBRARY_VERSION_TLS_1_3) {}
 
 TlsConnectGenericResumptionToken::TlsConnectGenericResumptionToken()
     : TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {}
 
 void TlsKeyExchangeTest::EnsureKeyShareSetup() {
   EnsureTlsSetup();
   groups_capture_ =
-      std::make_shared<TlsExtensionCapture>(ssl_supported_groups_xtn);
+      std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn);
   shares_capture_ =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn);
-  shares_capture2_ =
-      std::make_shared<TlsExtensionCapture>(ssl_tls13_key_share_xtn, true);
+      std::make_shared<TlsExtensionCapture>(client_, ssl_tls13_key_share_xtn);
+  shares_capture2_ = std::make_shared<TlsExtensionCapture>(
+      client_, ssl_tls13_key_share_xtn, true);
   std::vector<std::shared_ptr<PacketFilter>> captures = {
       groups_capture_, shares_capture_, shares_capture2_};
-  client_->SetPacketFilter(std::make_shared<ChainedPacketFilter>(captures));
-  capture_hrr_ = std::make_shared<TlsInspectorRecordHandshakeMessage>(
-      kTlsHandshakeHelloRetryRequest);
-  server_->SetPacketFilter(capture_hrr_);
+  client_->SetFilter(std::make_shared<ChainedPacketFilter>(captures));
+  capture_hrr_ = std::make_shared<TlsHandshakeRecorder>(
+      server_, kTlsHandshakeHelloRetryRequest);
+  server_->SetFilter(capture_hrr_);
 }
 
 void TlsKeyExchangeTest::ConfigNamedGroups(
     const std::vector<SSLNamedGroup>& groups) {
   client_->ConfigNamedGroups(groups);
   server_->ConfigNamedGroups(groups);
 }
 
--- a/gtests/ssl_gtest/tls_connect.h
+++ b/gtests/ssl_gtest/tls_connect.h
@@ -40,18 +40,18 @@ class TlsConnectTestBase : public ::test
   static ::testing::internal::ParamGenerator<uint16_t> kTlsV13;
   static ::testing::internal::ParamGenerator<uint16_t> kTlsV11Plus;
   static ::testing::internal::ParamGenerator<uint16_t> kTlsV12Plus;
   static ::testing::internal::ParamGenerator<uint16_t> kTlsVAll;
 
   TlsConnectTestBase(SSLProtocolVariant variant, uint16_t version);
   virtual ~TlsConnectTestBase();
 
-  void SetUp();
-  void TearDown();
+  virtual void SetUp();
+  virtual void TearDown();
 
   // Initialize client and server.
   void Init();
   // Clear the statistics.
   void ClearStats();
   // Clear the server session cache.
   void ClearServerCache();
   // Make sure TLS is configured for a connection.
@@ -315,17 +315,17 @@ class TlsConnectDatagramPre13 : public T
 class TlsConnectGenericPre13 : public TlsConnectGeneric {};
 class TlsConnectStreamResumptionPre13 : public TlsConnectGenericResumption {};
 
 class TlsKeyExchangeTest : public TlsConnectGeneric {
  protected:
   std::shared_ptr<TlsExtensionCapture> groups_capture_;
   std::shared_ptr<TlsExtensionCapture> shares_capture_;
   std::shared_ptr<TlsExtensionCapture> shares_capture2_;
-  std::shared_ptr<TlsInspectorRecordHandshakeMessage> capture_hrr_;
+  std::shared_ptr<TlsHandshakeRecorder> capture_hrr_;
 
   void EnsureKeyShareSetup();
   void ConfigNamedGroups(const std::vector<SSLNamedGroup>& groups);
   std::vector<SSLNamedGroup> GetGroupDetails(
       const std::shared_ptr<TlsExtensionCapture>& capture);
   std::vector<SSLNamedGroup> GetShareDetails(
       const std::shared_ptr<TlsExtensionCapture>& capture);
   void CheckKEXDetails(const std::vector<SSLNamedGroup>& expectedGroups,
--- a/gtests/ssl_gtest/tls_filter.cc
+++ b/gtests/ssl_gtest/tls_filter.cc
@@ -447,17 +447,17 @@ size_t TlsHandshakeFilter::HandshakeHead
     return WriteFragment(buffer, offset, body, 0U, body.len());
   }
   offset = buffer->Write(offset, handshake_type(), 1);
   offset = buffer->Write(offset, body.len(), 3);
   offset = buffer->Write(offset, body);
   return offset;
 }
 
-PacketFilter::Action TlsInspectorRecordHandshakeMessage::FilterHandshake(
+PacketFilter::Action TlsHandshakeRecorder::FilterHandshake(
     const HandshakeHeader& header, const DataBuffer& input,
     DataBuffer* output) {
   // Only do this once.
   if (buffer_.len()) {
     return KEEP;
   }
 
   buffer_ = input;
@@ -758,26 +758,26 @@ PacketFilter::Action TlsExtensionInjecto
 }
 
 PacketFilter::Action AfterRecordN::FilterRecord(const TlsRecordHeader& header,
                                                 const DataBuffer& body,
                                                 DataBuffer* out) {
   if (counter_++ == record_) {
     DataBuffer buf;
     header.Write(&buf, 0, body);
-    src_.lock()->SendDirect(buf);
+    agent()->SendDirect(buf);
     dest_.lock()->Handshake();
     func_();
     return DROP;
   }
 
   return KEEP;
 }
 
-PacketFilter::Action TlsInspectorClientHelloVersionChanger::FilterHandshake(
+PacketFilter::Action TlsClientHelloVersionChanger::FilterHandshake(
     const HandshakeHeader& header, const DataBuffer& input,
     DataBuffer* output) {
   EXPECT_EQ(SECSuccess,
             SSLInt_IncrementClientHandshakeVersion(server_.lock()->ssl_fd()));
   return KEEP;
 }
 
 PacketFilter::Action SelectiveDropFilter::Filter(const DataBuffer& input,
@@ -803,17 +803,17 @@ PacketFilter::Action SelectiveRecordDrop
   for (auto it = records.begin(); it != records.end(); ++it) {
     EXPECT_GT(32U, *it);
     assert(*it < 32U);
     pattern |= 1 << *it;
   }
   return pattern;
 }
 
-PacketFilter::Action TlsInspectorClientHelloVersionSetter::FilterHandshake(
+PacketFilter::Action TlsClientHelloVersionSetter::FilterHandshake(
     const HandshakeHeader& header, const DataBuffer& input,
     DataBuffer* output) {
   *output = input;
   output->Write(0, version_, 2);
   return CHANGE;
 }
 
 PacketFilter::Action SelectedCipherSuiteReplacer::FilterHandshake(
--- a/gtests/ssl_gtest/tls_filter.h
+++ b/gtests/ssl_gtest/tls_filter.h
@@ -69,26 +69,25 @@ class TlsRecordHeader : public TlsVersio
 struct TlsRecord {
   const TlsRecordHeader header;
   const DataBuffer buffer;
 };
 
 // Abstract filter that operates on entire (D)TLS records.
 class TlsRecordFilter : public PacketFilter {
  public:
-  TlsRecordFilter()
-      : agent_(nullptr),
+  TlsRecordFilter(const std::shared_ptr<TlsAgent>& agent)
+      : agent_(agent),
         count_(0),
         cipher_spec_(),
         dropped_record_(false),
         in_sequence_number_(0),
         out_sequence_number_(0) {}
 
-  void SetAgent(const TlsAgent* agent) { agent_ = agent; }
-  const TlsAgent* agent() const { return agent_; }
+  std::shared_ptr<TlsAgent> agent() const { return agent_.lock(); }
 
   // External interface. Overrides PacketFilter.
   PacketFilter::Action Filter(const DataBuffer& input, DataBuffer* output);
 
   // Report how many packets were altered by the filter.
   size_t filtered_packets() const { return count_; }
 
   // Enable decryption. This only works properly for TLS 1.3 and above.
@@ -121,17 +120,17 @@ class TlsRecordFilter : public PacketFil
                                             DataBuffer* changed) {
     return KEEP;
   }
 
  private:
   static void CipherSpecChanged(void* arg, PRBool sending,
                                 ssl3CipherSpec* newSpec);
 
-  const TlsAgent* agent_;
+  std::weak_ptr<TlsAgent> agent_;
   size_t count_;
   std::unique_ptr<TlsCipherSpec> cipher_spec_;
   // Whether we dropped a record since the cipher spec changed.
   bool dropped_record_;
   // The sequence number we use for reading records as they are written.
   uint64_t in_sequence_number_;
   // The sequence number we use for writing modified records.
   uint64_t out_sequence_number_;
@@ -170,19 +169,23 @@ inline std::ostream& operator<<(std::ost
   return stream << ' ' << std::hex << hdr.sequence_number() << std::dec;
 }
 
 // Abstract filter that operates on handshake messages rather than records.
 // This assumes that the handshake messages are written in a block as entire
 // records and that they don't span records or anything crazy like that.
 class TlsHandshakeFilter : public TlsRecordFilter {
  public:
-  TlsHandshakeFilter() : handshake_types_(), preceding_fragment_() {}
-  TlsHandshakeFilter(const std::set<uint8_t>& types)
-      : handshake_types_(types), preceding_fragment_() {}
+  TlsHandshakeFilter(const std::shared_ptr<TlsAgent>& agent)
+      : TlsRecordFilter(agent), handshake_types_(), preceding_fragment_() {}
+  TlsHandshakeFilter(const std::shared_ptr<TlsAgent>& agent,
+                     const std::set<uint8_t>& types)
+      : TlsRecordFilter(agent),
+        handshake_types_(types),
+        preceding_fragment_() {}
 
   // This filter can be set to be selective based on handshake message type.  If
   // this function isn't used (or the set is empty), then all handshake messages
   // will be filtered.
   void SetHandshakeTypes(const std::set<uint8_t>& types) {
     handshake_types_ = types;
   }
 
@@ -224,56 +227,61 @@ class TlsHandshakeFilter : public TlsRec
   bool IsFilteredType(const HandshakeHeader& header,
                       const DataBuffer& handshake);
 
   std::set<uint8_t> handshake_types_;
   DataBuffer preceding_fragment_;
 };
 
 // Make a copy of the first instance of a handshake message.
-class TlsInspectorRecordHandshakeMessage : public TlsHandshakeFilter {
+class TlsHandshakeRecorder : public TlsHandshakeFilter {
  public:
-  TlsInspectorRecordHandshakeMessage(uint8_t handshake_type)
-      : TlsHandshakeFilter({handshake_type}), buffer_() {}
-  TlsInspectorRecordHandshakeMessage(const std::set<uint8_t>& handshake_types)
-      : TlsHandshakeFilter(handshake_types), buffer_() {}
+  TlsHandshakeRecorder(const std::shared_ptr<TlsAgent>& agent,
+                       uint8_t handshake_type)
+      : TlsHandshakeFilter(agent, {handshake_type}), buffer_() {}
+  TlsHandshakeRecorder(const std::shared_ptr<TlsAgent>& agent,
+                       const std::set<uint8_t>& handshake_types)
+      : TlsHandshakeFilter(agent, handshake_types), buffer_() {}
 
   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                                const DataBuffer& input,
                                                DataBuffer* output);
 
   void Reset() { buffer_.Truncate(0); }
 
   const DataBuffer& buffer() const { return buffer_; }
 
  private:
   DataBuffer buffer_;
 };
 
 // Replace all instances of a handshake message.
 class TlsInspectorReplaceHandshakeMessage : public TlsHandshakeFilter {
  public:
-  TlsInspectorReplaceHandshakeMessage(uint8_t handshake_type,
+  TlsInspectorReplaceHandshakeMessage(const std::shared_ptr<TlsAgent>& agent,
+                                      uint8_t handshake_type,
                                       const DataBuffer& replacement)
-      : TlsHandshakeFilter({handshake_type}), buffer_(replacement) {}
+      : TlsHandshakeFilter(agent, {handshake_type}), buffer_(replacement) {}
 
   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                                const DataBuffer& input,
                                                DataBuffer* output);
 
  private:
   DataBuffer buffer_;
 };
 
 // Make a copy of each record of a given type.
 class TlsRecordRecorder : public TlsRecordFilter {
  public:
-  TlsRecordRecorder(uint8_t ct) : filter_(true), ct_(ct), records_() {}
-  TlsRecordRecorder()
-      : filter_(false),
+  TlsRecordRecorder(const std::shared_ptr<TlsAgent>& agent, uint8_t ct)
+      : TlsRecordFilter(agent), filter_(true), ct_(ct), records_() {}
+  TlsRecordRecorder(const std::shared_ptr<TlsAgent>& agent)
+      : TlsRecordFilter(agent),
+        filter_(false),
         ct_(content_handshake),  // dummy (<optional> is C++14)
         records_() {}
   virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                             const DataBuffer& input,
                                             DataBuffer* output);
 
   size_t count() const { return records_.size(); }
   void Clear() { records_.clear(); }
@@ -284,29 +292,33 @@ class TlsRecordRecorder : public TlsReco
   bool filter_;
   uint8_t ct_;
   std::vector<TlsRecord> records_;
 };
 
 // Make a copy of the complete conversation.
 class TlsConversationRecorder : public TlsRecordFilter {
  public:
-  TlsConversationRecorder(DataBuffer& buffer) : buffer_(buffer) {}
+  TlsConversationRecorder(const std::shared_ptr<TlsAgent>& agent,
+                          DataBuffer& buffer)
+      : TlsRecordFilter(agent), buffer_(buffer) {}
 
   virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                             const DataBuffer& input,
                                             DataBuffer* output);
 
  private:
   DataBuffer buffer_;
 };
 
 // Make a copy of the records
 class TlsHeaderRecorder : public TlsRecordFilter {
  public:
+  TlsHeaderRecorder(const std::shared_ptr<TlsAgent>& agent)
+      : TlsRecordFilter(agent) {}
   virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                             const DataBuffer& input,
                                             DataBuffer* output);
   const TlsRecordHeader* header(size_t index);
 
  private:
   std::vector<TlsRecordHeader> headers_;
 };
@@ -333,23 +345,25 @@ class ChainedPacketFilter : public Packe
   std::vector<std::shared_ptr<PacketFilter>> filters_;
 };
 
 typedef std::function<bool(TlsParser* parser, const TlsVersioned& header)>
     TlsExtensionFinder;
 
 class TlsExtensionFilter : public TlsHandshakeFilter {
  public:
-  TlsExtensionFilter()
-      : TlsHandshakeFilter({kTlsHandshakeClientHello, kTlsHandshakeServerHello,
+  TlsExtensionFilter(const std::shared_ptr<TlsAgent>& agent)
+      : TlsHandshakeFilter(agent,
+                           {kTlsHandshakeClientHello, kTlsHandshakeServerHello,
                             kTlsHandshakeHelloRetryRequest,
                             kTlsHandshakeEncryptedExtensions}) {}
 
-  TlsExtensionFilter(const std::set<uint8_t>& types)
-      : TlsHandshakeFilter(types) {}
+  TlsExtensionFilter(const std::shared_ptr<TlsAgent>& agent,
+                     const std::set<uint8_t>& types)
+      : TlsHandshakeFilter(agent, types) {}
 
   static bool FindExtensions(TlsParser* parser, const HandshakeHeader& header);
 
  protected:
   PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                        const DataBuffer& input,
                                        DataBuffer* output) override;
 
@@ -360,18 +374,23 @@ class TlsExtensionFilter : public TlsHan
  private:
   PacketFilter::Action FilterExtensions(TlsParser* parser,
                                         const DataBuffer& input,
                                         DataBuffer* output);
 };
 
 class TlsExtensionCapture : public TlsExtensionFilter {
  public:
-  TlsExtensionCapture(uint16_t ext, bool last = false)
-      : extension_(ext), captured_(false), last_(last), data_() {}
+  TlsExtensionCapture(const std::shared_ptr<TlsAgent>& agent, uint16_t ext,
+                      bool last = false)
+      : TlsExtensionFilter(agent),
+        extension_(ext),
+        captured_(false),
+        last_(last),
+        data_() {}
 
   const DataBuffer& extension() const { return data_; }
   bool captured() const { return captured_; }
 
  protected:
   PacketFilter::Action FilterExtension(uint16_t extension_type,
                                        const DataBuffer& input,
                                        DataBuffer* output) override;
@@ -380,79 +399,89 @@ class TlsExtensionCapture : public TlsEx
   const uint16_t extension_;
   bool captured_;
   bool last_;
   DataBuffer data_;
 };
 
 class TlsExtensionReplacer : public TlsExtensionFilter {
  public:
-  TlsExtensionReplacer(uint16_t extension, const DataBuffer& data)
-      : extension_(extension), data_(data) {}
+  TlsExtensionReplacer(const std::shared_ptr<TlsAgent>& agent,
+                       uint16_t extension, const DataBuffer& data)
+      : TlsExtensionFilter(agent), extension_(extension), data_(data) {}
   PacketFilter::Action FilterExtension(uint16_t extension_type,
                                        const DataBuffer& input,
                                        DataBuffer* output) override;
 
  private:
   const uint16_t extension_;
   const DataBuffer data_;
 };
 
 class TlsExtensionDropper : public TlsExtensionFilter {
  public:
-  TlsExtensionDropper(uint16_t extension) : extension_(extension) {}
+  TlsExtensionDropper(const std::shared_ptr<TlsAgent>& agent,
+                      uint16_t extension)
+      : TlsExtensionFilter(agent), extension_(extension) {}
   PacketFilter::Action FilterExtension(uint16_t extension_type,
                                        const DataBuffer&, DataBuffer*) override;
 
  private:
   uint16_t extension_;
 };
 
 class TlsExtensionInjector : public TlsHandshakeFilter {
  public:
-  TlsExtensionInjector(uint16_t ext, const DataBuffer& data)
-      : extension_(ext), data_(data) {}
+  TlsExtensionInjector(const std::shared_ptr<TlsAgent>& agent, uint16_t ext,
+                       const DataBuffer& data)
+      : TlsHandshakeFilter(agent), extension_(ext), data_(data) {}
 
  protected:
   PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                        const DataBuffer& input,
                                        DataBuffer* output) override;
 
  private:
   const uint16_t extension_;
   const DataBuffer data_;
 };
 
 class TlsAgent;
 typedef std::function<void(void)> VoidFunction;
 
 class AfterRecordN : public TlsRecordFilter {
  public:
-  AfterRecordN(std::shared_ptr<TlsAgent>& src, std::shared_ptr<TlsAgent>& dest,
-               unsigned int record, VoidFunction func)
-      : src_(src), dest_(dest), record_(record), func_(func), counter_(0) {}
+  AfterRecordN(const std::shared_ptr<TlsAgent>& src,
+               const std::shared_ptr<TlsAgent>& dest, unsigned int record,
+               VoidFunction func)
+      : TlsRecordFilter(src),
+        dest_(dest),
+        record_(record),
+        func_(func),
+        counter_(0) {}
 
   virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
                                             const DataBuffer& body,
                                             DataBuffer* out) override;
 
  private:
-  std::weak_ptr<TlsAgent> src_;
   std::weak_ptr<TlsAgent> dest_;
   unsigned int record_;
   VoidFunction func_;
   unsigned int counter_;
 };
 
 // When we see the ClientKeyExchange from |client|, increment the
 // ClientHelloVersion on |server|.
-class TlsInspectorClientHelloVersionChanger : public TlsHandshakeFilter {
+class TlsClientHelloVersionChanger : public TlsHandshakeFilter {
  public:
-  TlsInspectorClientHelloVersionChanger(std::shared_ptr<TlsAgent>& server)
-      : TlsHandshakeFilter({kTlsHandshakeClientKeyExchange}), server_(server) {}
+  TlsClientHelloVersionChanger(const std::shared_ptr<TlsAgent>& client,
+                               const std::shared_ptr<TlsAgent>& server)
+      : TlsHandshakeFilter(client, {kTlsHandshakeClientKeyExchange}),
+        server_(server) {}
 
   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                                const DataBuffer& input,
                                                DataBuffer* output);
 
  private:
   std::weak_ptr<TlsAgent> server_;
 };
@@ -472,24 +501,26 @@ class SelectiveDropFilter : public Packe
   uint8_t counter_;
 };
 
 // This class selectively drops complete records. The difference from
 // SelectiveDropFilter is that if multiple DTLS records are in the same
 // datagram, we just drop one.
 class SelectiveRecordDropFilter : public TlsRecordFilter {
  public:
-  SelectiveRecordDropFilter(uint32_t pattern, bool enabled = true)
-      : pattern_(pattern), counter_(0) {
+  SelectiveRecordDropFilter(const std::shared_ptr<TlsAgent>& agent,
+                            uint32_t pattern, bool enabled = true)
+      : TlsRecordFilter(agent), pattern_(pattern), counter_(0) {
     if (!enabled) {
       Disable();
     }
   }
-  SelectiveRecordDropFilter(std::initializer_list<size_t> records)
-      : SelectiveRecordDropFilter(ToPattern(records), true) {}
+  SelectiveRecordDropFilter(const std::shared_ptr<TlsAgent>& agent,
+                            std::initializer_list<size_t> records)
+      : SelectiveRecordDropFilter(agent, ToPattern(records), true) {}
 
   void Reset(uint32_t pattern) {
     counter_ = 0;
     PacketFilter::Enable();
     pattern_ = pattern;
   }
 
   void Reset(std::initializer_list<size_t> records) {
@@ -504,33 +535,36 @@ class SelectiveRecordDropFilter : public
  private:
   static uint32_t ToPattern(std::initializer_list<size_t> records);
 
   uint32_t pattern_;
   uint8_t counter_;
 };
 
 // Set the version number in the ClientHello.
-class TlsInspectorClientHelloVersionSetter : public TlsHandshakeFilter {
+class TlsClientHelloVersionSetter : public TlsHandshakeFilter {
  public:
-  TlsInspectorClientHelloVersionSetter(uint16_t version)
-      : TlsHandshakeFilter({kTlsHandshakeClientHello}), version_(version) {}
+  TlsClientHelloVersionSetter(const std::shared_ptr<TlsAgent>& agent,
+                              uint16_t version)
+      : TlsHandshakeFilter(agent, {kTlsHandshakeClientHello}),
+        version_(version) {}
 
   virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                                const DataBuffer& input,
                                                DataBuffer* output);
 
  private:
   uint16_t version_;
 };
 
 // Damages the last byte of a handshake message.
 class TlsLastByteDamager : public TlsHandshakeFilter {
  public:
-  TlsLastByteDamager(uint8_t type) : type_(type) {}
+  TlsLastByteDamager(const std::shared_ptr<TlsAgent>& agent, uint8_t type)
+      : TlsHandshakeFilter(agent), type_(type) {}
   PacketFilter::Action FilterHandshake(
       const TlsHandshakeFilter::HandshakeHeader& header,
       const DataBuffer& input, DataBuffer* output) override {
     if (header.handshake_type() != type_) {
       return KEEP;
     }
 
     *output = input;
@@ -540,18 +574,20 @@ class TlsLastByteDamager : public TlsHan
   }
 
  private:
   uint8_t type_;
 };
 
 class SelectedCipherSuiteReplacer : public TlsHandshakeFilter {
  public:
-  SelectedCipherSuiteReplacer(uint16_t suite)
-      : TlsHandshakeFilter({kTlsHandshakeServerHello}), cipher_suite_(suite) {}
+  SelectedCipherSuiteReplacer(const std::shared_ptr<TlsAgent>& agent,
+                              uint16_t suite)
+      : TlsHandshakeFilter(agent, {kTlsHandshakeServerHello}),
+        cipher_suite_(suite) {}
 
  protected:
   PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                        const DataBuffer& input,
                                        DataBuffer* output) override;
 
  private:
   uint16_t cipher_suite_;