Add a new Tunnel Health Checker. The health checker is configured to
run about every 5th ICMP probe and checks the packet exchanger's
counters in both directions. If *no* packets have passed in one
direction, this will tear down the tunnel, leaving it to be restarted on
the next epoll cycle.

gfe-relnote: n/a (QBONE-only change)
PiperOrigin-RevId: 275474401
Change-Id: I934c45ff35d855593518ce76f4f2d9326e269adb
diff --git a/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h b/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h
new file mode 100644
index 0000000..f74e2a3
--- /dev/null
+++ b/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
+#define QUICHE_QUIC_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
+
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger.h"
+
+namespace quic {
+
+class MockPacketExchangerStatsInterface
+    : public TunDevicePacketExchanger::StatsInterface {
+ public:
+  MOCK_METHOD0(OnPacketRead, void());
+  MOCK_METHOD0(OnPacketWritten, void());
+  MOCK_METHOD1(OnReadError, void(string*));
+  MOCK_METHOD1(OnWriteError, void(string*));
+
+  MOCK_CONST_METHOD0(PacketsRead, int64_t());
+  MOCK_CONST_METHOD0(PacketsWritten, int64_t());
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_QBONE_BONNET_MOCK_PACKET_EXCHANGER_STATS_INTERFACE_H_
diff --git a/quic/qbone/bonnet/tun_device_packet_exchanger.cc b/quic/qbone/bonnet/tun_device_packet_exchanger.cc
index 799247c..37fd2c0 100644
--- a/quic/qbone/bonnet/tun_device_packet_exchanger.cc
+++ b/quic/qbone/bonnet/tun_device_packet_exchanger.cc
@@ -81,4 +81,9 @@
   return fd_;
 }
 
+const TunDevicePacketExchanger::StatsInterface*
+TunDevicePacketExchanger::stats_interface() const {
+  return stats_;
+}
+
 }  // namespace quic
diff --git a/quic/qbone/bonnet/tun_device_packet_exchanger.h b/quic/qbone/bonnet/tun_device_packet_exchanger.h
index 12d9efa..42ed7fb 100644
--- a/quic/qbone/bonnet/tun_device_packet_exchanger.h
+++ b/quic/qbone/bonnet/tun_device_packet_exchanger.h
@@ -30,6 +30,9 @@
     virtual void OnPacketWritten() = 0;
     virtual void OnReadError(string* error) = 0;
     virtual void OnWriteError(string* error) = 0;
+
+    ABSL_MUST_USE_RESULT virtual int64_t PacketsRead() const = 0;
+    ABSL_MUST_USE_RESULT virtual int64_t PacketsWritten() const = 0;
   };
 
   // |fd| is a open file descriptor on a TUN device that's opened for both read
@@ -48,7 +51,9 @@
                            size_t max_pending_packets,
                            StatsInterface* stats);
 
-  int file_descriptor() const;
+  ABSL_MUST_USE_RESULT int file_descriptor() const;
+
+  ABSL_MUST_USE_RESULT const StatsInterface* stats_interface() const;
 
  private:
   // From QbonePacketExchanger.
diff --git a/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc b/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
index 026ec26..0f25e73 100644
--- a/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
+++ b/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc
@@ -5,6 +5,7 @@
 #include "net/third_party/quiche/src/quic/qbone/bonnet/tun_device_packet_exchanger.h"
 
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/qbone/bonnet/mock_packet_exchanger_stats_interface.h"
 #include "net/third_party/quiche/src/quic/qbone/mock_qbone_client.h"
 #include "net/third_party/quiche/src/quic/qbone/platform/mock_kernel.h"
 
@@ -26,15 +27,6 @@
   MOCK_METHOD1(OnWriteError, void(const string&));
 };
 
-class MockStatsInterface : public TunDevicePacketExchanger::StatsInterface {
- public:
-  MOCK_METHOD0(OnPacketRead, void());
-  MOCK_METHOD0(OnPacketWritten, void());
-
-  MOCK_METHOD1(OnReadError, void(string*));
-  MOCK_METHOD1(OnWriteError, void(string*));
-};
-
 class TunDevicePacketExchangerTest : public QuicTest {
  protected:
   TunDevicePacketExchangerTest()
@@ -50,7 +42,7 @@
   MockKernel mock_kernel_;
   StrictMock<MockVisitor> mock_visitor_;
   StrictMock<MockQboneClient> mock_client_;
-  StrictMock<MockStatsInterface> mock_stats_;
+  StrictMock<MockPacketExchangerStatsInterface> mock_stats_;
   TunDevicePacketExchanger exchanger_;
 };