diff --git a/tools/get/README.md b/tools/get/README.md
new file mode 100644
index 0000000..90774c9
--- /dev/null
+++ b/tools/get/README.md
@@ -0,0 +1,44 @@
+# ndnget
+
+**ndnget** is a consumer program that fetches the segments (Data packets) of a named object,
+optionally discovering the latest version of the object, and then writes the content of the
+retrieved object to the standard output.
+
+## Version discovery in ndnget
+
+If a version component is present at the end of the user-specified NDN name, the provided version
+number will be used, without any version discovery process. Otherwise, discovery Interest(s) will
+be sent out to fetch metadata of the solicited content from which the Data version will be resolved.
+For more information about the packet format and naming conventions of Interest and Data packets
+used for version discovery in ndnget, please refer to:
+[Realtime Data Retrieval (RDR) protocol](https://redmine.named-data.net/projects/ndn-tlv/wiki/RDR).
+
+## Interest pipeline types in ndnget
+
+* `fixed`: maintains a fixed-size window of Interests in flight; the window size is configurable
+           via a command line option and defaults to 1.
+
+* `aimd` : adjusts the window size via additive-increase/multiplicative-decrease (AIMD).
+           By default, it uses a Conservative Window Adaptation, that is, the congestion window
+           will be decreased at most once per round-trip-time.
+
+* `cubic`: adjusts the window size similar to the TCP CUBIC algorithm.
+           For details about both aimd and cubic please refer to:
+           [A Practical Congestion Control Scheme for Named Data
+           Networking](https://conferences2.sigcomm.org/acm-icn/2016/proceedings/p21-schneider.pdf).
+
+The default Interest pipeline type is `cubic`.
+
+## Usage examples
+
+To retrieve the latest version of a published object, the following command can be used:
+
+    ndnget /localhost/demo/gpl3
+
+To fetch a specific version of a published object, you can specify the version number at the end
+of the name. For example, if the version is known to be 1449078495094, the following command
+will fetch that exact version of the object (without version discovery):
+
+    ndnget -Nt /localhost/demo/gpl3/v=1449078495094
+
+For more information, run the programs with `--help` as argument.
diff --git a/tools/get/consumer.cpp b/tools/get/consumer.cpp
new file mode 100644
index 0000000..10b9d04
--- /dev/null
+++ b/tools/get/consumer.cpp
@@ -0,0 +1,90 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Wentao Shang
+ * @author Steve DiBenedetto
+ * @author Andrea Tosatto
+ */
+
+#include "consumer.hpp"
+
+#include <ndn-cxx/util/exception.hpp>
+
+namespace ndn::get {
+
+Consumer::Consumer(security::Validator& validator, std::ostream& os)
+  : m_validator(validator)
+  , m_outputStream(os)
+{
+}
+
+void
+Consumer::run(std::unique_ptr<DiscoverVersion> discover, std::unique_ptr<PipelineInterests> pipeline)
+{
+  m_discover = std::move(discover);
+  m_pipeline = std::move(pipeline);
+  m_nextToPrint = 0;
+  m_bufferedData.clear();
+
+  m_discover->onDiscoverySuccess.connect([this] (const Name& versionedName) {
+    m_pipeline->run(versionedName,
+                    FORWARD_TO_MEM_FN(handleData),
+                    [] (const std::string& msg) { NDN_THROW(std::runtime_error(msg)); });
+  });
+  m_discover->onDiscoveryFailure.connect([] (const std::string& msg) {
+    NDN_THROW(std::runtime_error(msg));
+  });
+  m_discover->run();
+}
+
+void
+Consumer::handleData(const Data& data)
+{
+  auto dataPtr = data.shared_from_this();
+
+  m_validator.validate(data,
+    [this, dataPtr] (const Data& data) {
+      if (data.getContentType() == ndn::tlv::ContentType_Nack) {
+        NDN_THROW(ApplicationNackError(data));
+      }
+
+      // 'data' passed to callback comes from DataValidationState and was not created with make_shared
+      m_bufferedData[getSegmentFromPacket(data)] = dataPtr;
+      writeInOrderData();
+    },
+    [] (const Data&, const security::ValidationError& error) {
+      NDN_THROW(DataValidationError(error));
+    });
+}
+
+void
+Consumer::writeInOrderData()
+{
+  for (auto it = m_bufferedData.begin();
+       it != m_bufferedData.end() && it->first == m_nextToPrint;
+       it = m_bufferedData.erase(it), ++m_nextToPrint) {
+    const Block& content = it->second->getContent();
+    m_outputStream.write(reinterpret_cast<const char*>(content.value()), content.value_size());
+  }
+}
+
+} // namespace ndn::get
diff --git a/tools/get/consumer.hpp b/tools/get/consumer.hpp
new file mode 100644
index 0000000..9e40dba
--- /dev/null
+++ b/tools/get/consumer.hpp
@@ -0,0 +1,106 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Wentao Shang
+ * @author Steve DiBenedetto
+ * @author Andrea Tosatto
+ */
+
+#ifndef NDN_TOOLS_GET_CONSUMER_HPP
+#define NDN_TOOLS_GET_CONSUMER_HPP
+
+#include "discover-version.hpp"
+#include "pipeline-interests.hpp"
+
+#include <ndn-cxx/security/validation-error.hpp>
+#include <ndn-cxx/security/validator.hpp>
+
+#include <boost/lexical_cast.hpp>
+#include <iostream>
+#include <map>
+
+namespace ndn::get {
+
+/**
+ * @brief Segmented version consumer.
+ *
+ * Discover the latest version of the data published under a specified prefix, and retrieve all the
+ * segments associated to that version. The segments are fetched in order and written to a
+ * user-specified stream in the same order.
+ */
+class Consumer : noncopyable
+{
+public:
+  class ApplicationNackError : public std::runtime_error
+  {
+  public:
+    explicit
+    ApplicationNackError(const Data& data)
+      : std::runtime_error("Application generated Nack: " + boost::lexical_cast<std::string>(data))
+    {
+    }
+  };
+
+  class DataValidationError : public std::runtime_error
+  {
+  public:
+    explicit
+    DataValidationError(const security::ValidationError& error)
+      : std::runtime_error(boost::lexical_cast<std::string>(error))
+    {
+    }
+  };
+
+  /**
+   * @brief Create the consumer
+   */
+  explicit
+  Consumer(security::Validator& validator, std::ostream& os = std::cout);
+
+  /**
+   * @brief Run the consumer
+   */
+  void
+  run(std::unique_ptr<DiscoverVersion> discover, std::unique_ptr<PipelineInterests> pipeline);
+
+private:
+  void
+  handleData(const Data& data);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  void
+  writeInOrderData();
+
+private:
+  security::Validator& m_validator;
+  std::ostream& m_outputStream;
+  std::unique_ptr<DiscoverVersion> m_discover;
+  std::unique_ptr<PipelineInterests> m_pipeline;
+  uint64_t m_nextToPrint = 0;
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  std::map<uint64_t, std::shared_ptr<const Data>> m_bufferedData;
+};
+
+} // namespace ndn::get
+
+#endif // NDN_TOOLS_GET_CONSUMER_HPP
diff --git a/tools/get/data-fetcher.cpp b/tools/get/data-fetcher.cpp
new file mode 100644
index 0000000..1f3506a
--- /dev/null
+++ b/tools/get/data-fetcher.cpp
@@ -0,0 +1,176 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Andrea Tosatto
+ * @author Davide Pesavento
+ */
+
+#include "data-fetcher.hpp"
+
+#include <boost/lexical_cast.hpp>
+
+#include <cmath>
+#include <iostream>
+
+namespace ndn::get {
+
+std::shared_ptr<DataFetcher>
+DataFetcher::fetch(Face& face, const Interest& interest, int maxNackRetries, int maxTimeoutRetries,
+                   DataCallback onData, FailureCallback onNack, FailureCallback onTimeout,
+                   bool isVerbose)
+{
+  auto dataFetcher = std::shared_ptr<DataFetcher>(new DataFetcher(face,
+                                                                  maxNackRetries,
+                                                                  maxTimeoutRetries,
+                                                                  std::move(onData),
+                                                                  std::move(onNack),
+                                                                  std::move(onTimeout),
+                                                                  isVerbose));
+  dataFetcher->expressInterest(interest, dataFetcher);
+  return dataFetcher;
+}
+
+DataFetcher::DataFetcher(Face& face, int maxNackRetries, int maxTimeoutRetries,
+                         DataCallback onData, FailureCallback onNack, FailureCallback onTimeout,
+                         bool isVerbose)
+  : m_face(face)
+  , m_scheduler(m_face.getIoContext())
+  , m_onData(std::move(onData))
+  , m_onNack(std::move(onNack))
+  , m_onTimeout(std::move(onTimeout))
+  , m_maxNackRetries(maxNackRetries)
+  , m_maxTimeoutRetries(maxTimeoutRetries)
+  , m_isVerbose(isVerbose)
+{
+  BOOST_ASSERT(m_onData != nullptr);
+}
+
+void
+DataFetcher::cancel()
+{
+  if (isRunning()) {
+    m_isStopped = true;
+    m_pendingInterest.cancel();
+    m_scheduler.cancelAllEvents();
+  }
+}
+
+void
+DataFetcher::expressInterest(const Interest& interest, const std::shared_ptr<DataFetcher>& self)
+{
+  m_nCongestionRetries = 0;
+  m_pendingInterest = m_face.expressInterest(interest,
+    [this, self] (auto&&... args) { handleData(std::forward<decltype(args)>(args)..., self); },
+    [this, self] (auto&&... args) { handleNack(std::forward<decltype(args)>(args)..., self); },
+    [this, self] (auto&&... args) { handleTimeout(std::forward<decltype(args)>(args)..., self); });
+}
+
+void
+DataFetcher::handleData(const Interest& interest, const Data& data,
+                        const std::shared_ptr<DataFetcher>& self)
+{
+  if (!isRunning())
+    return;
+
+  m_isStopped = true;
+  m_onData(interest, data);
+}
+
+void
+DataFetcher::handleNack(const Interest& interest, const lp::Nack& nack,
+                        const std::shared_ptr<DataFetcher>& self)
+{
+  if (!isRunning())
+    return;
+
+  if (m_maxNackRetries != MAX_RETRIES_INFINITE)
+    ++m_nNacks;
+
+  if (m_isVerbose)
+    std::cerr << "Received Nack with reason " << nack.getReason()
+              << " for Interest " << interest << "\n";
+
+  if (m_nNacks <= m_maxNackRetries || m_maxNackRetries == MAX_RETRIES_INFINITE) {
+    Interest newInterest(interest);
+    newInterest.refreshNonce();
+
+    switch (nack.getReason()) {
+      case lp::NackReason::DUPLICATE: {
+        expressInterest(newInterest, self);
+        break;
+      }
+      case lp::NackReason::CONGESTION: {
+        time::milliseconds backoffTime(static_cast<uint64_t>(std::pow(2, m_nCongestionRetries)));
+        if (backoffTime > MAX_CONGESTION_BACKOFF_TIME) {
+          backoffTime = MAX_CONGESTION_BACKOFF_TIME;
+        }
+        else {
+          m_nCongestionRetries++;
+        }
+        m_scheduler.schedule(backoffTime, [this, newInterest, self] {
+          expressInterest(newInterest, self);
+        });
+        break;
+      }
+      default: {
+        m_hasError = true;
+        if (m_onNack)
+          m_onNack(interest, "Could not retrieve data for " + interest.getName().toUri() +
+                             ", reason: " + boost::lexical_cast<std::string>(nack.getReason()));
+        break;
+      }
+    }
+  }
+  else {
+    m_hasError = true;
+    if (m_onNack)
+      m_onNack(interest, "Reached the maximum number of nack retries (" + std::to_string(m_maxNackRetries) +
+                         ") while retrieving data for " + interest.getName().toUri());
+  }
+}
+
+void
+DataFetcher::handleTimeout(const Interest& interest, const std::shared_ptr<DataFetcher>& self)
+{
+  if (!isRunning())
+    return;
+
+  if (m_maxTimeoutRetries != MAX_RETRIES_INFINITE)
+    ++m_nTimeouts;
+
+  if (m_isVerbose)
+    std::cerr << "Timeout for Interest " << interest << "\n";
+
+  if (m_nTimeouts <= m_maxTimeoutRetries || m_maxTimeoutRetries == MAX_RETRIES_INFINITE) {
+    Interest newInterest(interest);
+    newInterest.refreshNonce();
+    expressInterest(newInterest, self);
+  }
+  else {
+    m_hasError = true;
+    if (m_onTimeout)
+      m_onTimeout(interest, "Reached the maximum number of timeout retries (" + std::to_string(m_maxTimeoutRetries) +
+                            ") while retrieving data for " + interest.getName().toUri());
+  }
+}
+
+} // namespace ndn::get
diff --git a/tools/get/data-fetcher.hpp b/tools/get/data-fetcher.hpp
new file mode 100644
index 0000000..fa968a8
--- /dev/null
+++ b/tools/get/data-fetcher.hpp
@@ -0,0 +1,135 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Andrea Tosatto
+ * @author Davide Pesavento
+ */
+
+#ifndef NDN_TOOLS_GET_DATA_FETCHER_HPP
+#define NDN_TOOLS_GET_DATA_FETCHER_HPP
+
+#include "core/common.hpp"
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
+
+#include <functional>
+
+namespace ndn::get {
+
+/**
+ * @brief Fetch data for a given interest and handle timeout or nack error with retries.
+ *
+ * To instantiate a DataFetcher you need to use the static method fetch, this will also express the
+ * interest. After a timeout or nack is received, the same interest with a different nonce will be
+ * requested for a maximum number of time specified by the class user. There are separate retry
+ * counters for timeouts and nacks.
+ *
+ * A specified callback is called after the data matching the expressed interest is received. A
+ * different callback is called in case one of the retries counter reach the maximum. This callback
+ * can be different for timeout and nack. The data callback must be defined but the others callback
+ * are optional.
+ *
+ */
+class DataFetcher
+{
+public:
+  /**
+   * @brief means that there is no maximum number of retries,
+   *        i.e. fetching must be retried indefinitely
+   */
+  static constexpr int MAX_RETRIES_INFINITE = -1;
+
+  /**
+   * @brief ceiling value for backoff time used in congestion handling
+   */
+  static constexpr time::milliseconds MAX_CONGESTION_BACKOFF_TIME = 10_s;
+
+  using FailureCallback = std::function<void(const Interest& interest, const std::string& reason)>;
+
+  /**
+   * @brief instantiate a DataFetcher object and start fetching data
+   *
+   * @param onData callback for segment correctly received, must not be empty
+   */
+  static std::shared_ptr<DataFetcher>
+  fetch(Face& face, const Interest& interest, int maxNackRetries, int maxTimeoutRetries,
+        DataCallback onData, FailureCallback onTimeout, FailureCallback onNack,
+        bool isVerbose);
+
+  /**
+   * @brief stop data fetching without error and calling any callback
+   */
+  void
+  cancel();
+
+  bool
+  isRunning() const
+  {
+    return !m_isStopped && !m_hasError;
+  }
+
+  bool
+  hasError() const
+  {
+    return m_hasError;
+  }
+
+private:
+  DataFetcher(Face& face, int maxNackRetries, int maxTimeoutRetries,
+              DataCallback onData, FailureCallback onNack, FailureCallback onTimeout,
+              bool isVerbose);
+
+  void
+  expressInterest(const Interest& interest, const std::shared_ptr<DataFetcher>& self);
+
+  void
+  handleData(const Interest& interest, const Data& data, const std::shared_ptr<DataFetcher>& self);
+
+  void
+  handleNack(const Interest& interest, const lp::Nack& nack, const std::shared_ptr<DataFetcher>& self);
+
+  void
+  handleTimeout(const Interest& interest, const std::shared_ptr<DataFetcher>& self);
+
+private:
+  Face& m_face;
+  Scheduler m_scheduler;
+  PendingInterestHandle m_pendingInterest;
+  DataCallback m_onData;
+  FailureCallback m_onNack;
+  FailureCallback m_onTimeout;
+
+  int m_maxNackRetries;
+  int m_maxTimeoutRetries;
+  int m_nNacks = 0;
+  int m_nTimeouts = 0;
+  uint32_t m_nCongestionRetries = 0;
+
+  bool m_isVerbose = false;
+  bool m_isStopped = false;
+  bool m_hasError = false;
+};
+
+} // namespace ndn::get
+
+#endif // NDN_TOOLS_GET_DATA_FETCHER_HPP
diff --git a/tools/get/discover-version.cpp b/tools/get/discover-version.cpp
new file mode 100644
index 0000000..530e469
--- /dev/null
+++ b/tools/get/discover-version.cpp
@@ -0,0 +1,97 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Wentao Shang
+ * @author Steve DiBenedetto
+ * @author Andrea Tosatto
+ * @author Chavoosh Ghasemi
+ */
+
+#include "discover-version.hpp"
+#include "data-fetcher.hpp"
+
+#include <ndn-cxx/metadata-object.hpp>
+
+#include <iostream>
+
+namespace ndn::get {
+
+DiscoverVersion::DiscoverVersion(Face& face, const Name& prefix, const Options& options)
+  : m_face(face)
+  , m_prefix(prefix)
+  , m_options(options)
+{
+}
+
+void
+DiscoverVersion::run()
+{
+  if (m_options.disableVersionDiscovery || (!m_prefix.empty() && m_prefix[-1].isVersion())) {
+    onDiscoverySuccess(m_prefix);
+    return;
+  }
+
+  Interest interest = MetadataObject::makeDiscoveryInterest(m_prefix)
+                      .setInterestLifetime(m_options.interestLifetime);
+
+  m_fetcher = DataFetcher::fetch(m_face, interest,
+                                 m_options.maxRetriesOnTimeoutOrNack,
+                                 m_options.maxRetriesOnTimeoutOrNack,
+                                 FORWARD_TO_MEM_FN(handleData),
+                                 [this] (const auto&, const auto& reason) {
+                                   onDiscoveryFailure(reason);
+                                 },
+                                 [this] (const auto&, const auto& reason) {
+                                   onDiscoveryFailure(reason);
+                                 },
+                                 m_options.isVerbose);
+}
+
+void
+DiscoverVersion::handleData(const Interest& interest, const Data& data)
+{
+  if (m_options.isVerbose)
+    std::cerr << "Data: " << data << "\n";
+
+  // make a metadata object from received metadata packet
+  MetadataObject mobject;
+  try {
+    mobject = MetadataObject(data);
+  }
+  catch (const tlv::Error& e) {
+    onDiscoveryFailure("Invalid metadata packet: "s + e.what());
+    return;
+  }
+
+  if (mobject.getVersionedName().empty() || !mobject.getVersionedName()[-1].isVersion()) {
+    onDiscoveryFailure(mobject.getVersionedName().toUri() + " is not a valid versioned name");
+    return;
+  }
+
+  if (m_options.isVerbose) {
+    std::cerr << "Discovered Data version: " << mobject.getVersionedName()[-1] << "\n";
+  }
+
+  onDiscoverySuccess(mobject.getVersionedName());
+}
+
+} // namespace ndn::get
diff --git a/tools/get/discover-version.hpp b/tools/get/discover-version.hpp
new file mode 100644
index 0000000..99eaa18
--- /dev/null
+++ b/tools/get/discover-version.hpp
@@ -0,0 +1,78 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Wentao Shang
+ * @author Steve DiBenedetto
+ * @author Andrea Tosatto
+ * @author Chavoosh Ghasemi
+ */
+
+#ifndef NDN_TOOLS_GET_DISCOVER_VERSION_HPP
+#define NDN_TOOLS_GET_DISCOVER_VERSION_HPP
+
+#include "options.hpp"
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/util/signal.hpp>
+
+namespace ndn::get {
+
+class DataFetcher;
+
+/**
+ * @brief Service for discovering the latest Data version.
+ *
+ * DiscoverVersion's user is notified once after identifying the latest retrievable version or
+ * on failure to find any Data version.
+ */
+class DiscoverVersion
+{
+public:
+  DiscoverVersion(Face& face, const Name& prefix, const Options& options);
+
+  /**
+   * @brief Signal emitted when the versioned name of Data is found.
+   */
+  signal::Signal<DiscoverVersion, Name> onDiscoverySuccess;
+
+  /**
+   * @brief Signal emitted when a failure occurs.
+   */
+  signal::Signal<DiscoverVersion, std::string> onDiscoveryFailure;
+
+  void
+  run();
+
+private:
+  void
+  handleData(const Interest& interest, const Data& data);
+
+private:
+  Face& m_face;
+  const Name m_prefix;
+  const Options& m_options;
+  std::shared_ptr<DataFetcher> m_fetcher;
+};
+
+} // namespace ndn::get
+
+#endif // NDN_TOOLS_GET_DISCOVER_VERSION_HPP
diff --git a/tools/get/main.cpp b/tools/get/main.cpp
new file mode 100644
index 0000000..bd1a0e8
--- /dev/null
+++ b/tools/get/main.cpp
@@ -0,0 +1,319 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Wentao Shang
+ * @author Steve DiBenedetto
+ * @author Andrea Tosatto
+ * @author Davide Pesavento
+ * @author Weiwei Liu
+ * @author Klaus Schneider
+ * @author Chavoosh Ghasemi
+ */
+
+#include "consumer.hpp"
+#include "discover-version.hpp"
+#include "pipeline-interests-aimd.hpp"
+#include "pipeline-interests-cubic.hpp"
+#include "pipeline-interests-fixed.hpp"
+#include "statistics-collector.hpp"
+#include "core/version.hpp"
+
+#include <ndn-cxx/security/validator-null.hpp>
+#include <ndn-cxx/util/rtt-estimator.hpp>
+
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/parsers.hpp>
+#include <boost/program_options/variables_map.hpp>
+
+#include <fstream>
+#include <iostream>
+
+namespace ndn::get {
+
+namespace po = boost::program_options;
+
+static int
+main(int argc, char* argv[])
+{
+  const std::string programName(argv[0]);
+
+  Options options;
+  std::string prefix, nameConv, pipelineType("cubic");
+  std::string cwndPath, rttPath;
+  auto rttEstOptions = std::make_shared<util::RttEstimator::Options>();
+  rttEstOptions->k = 8; // increased from the ndn-cxx default of 4
+
+  po::options_description basicDesc("Basic Options");
+  basicDesc.add_options()
+    ("help,h",      "print this help message and exit")
+    ("fresh,f",     po::bool_switch(&options.mustBeFresh),
+                    "only return fresh content (set MustBeFresh on all outgoing Interests)")
+    ("lifetime,l",  po::value<time::milliseconds::rep>()->default_value(options.interestLifetime.count()),
+                    "lifetime of expressed Interests, in milliseconds")
+    ("retries,r",   po::value<int>(&options.maxRetriesOnTimeoutOrNack)->default_value(options.maxRetriesOnTimeoutOrNack),
+                    "maximum number of retries in case of Nack or timeout (-1 = no limit)")
+    ("pipeline-type,p", po::value<std::string>(&pipelineType)->default_value(pipelineType),
+                        "type of Interest pipeline to use; valid values are: 'fixed', 'aimd', 'cubic'")
+    ("no-version-discovery,D", po::bool_switch(&options.disableVersionDiscovery),
+                               "skip version discovery even if the name does not end with a version component")
+    ("naming-convention,N", po::value<std::string>(&nameConv),
+                            "encoding convention to use for name components, either 'marker' or 'typed'")
+    ("quiet,q",     po::bool_switch(&options.isQuiet), "suppress all diagnostic output, except fatal errors")
+    ("verbose,v",   po::bool_switch(&options.isVerbose), "turn on verbose output (per segment information")
+    ("version,V",   "print program version and exit")
+    ;
+
+  po::options_description fixedPipeDesc("Fixed pipeline options");
+  fixedPipeDesc.add_options()
+    ("pipeline-size,s", po::value<size_t>(&options.maxPipelineSize)->default_value(options.maxPipelineSize),
+                        "size of the Interest pipeline")
+    ;
+
+  po::options_description adaptivePipeDesc("Adaptive pipeline options (AIMD & CUBIC)");
+  adaptivePipeDesc.add_options()
+    ("ignore-marks",  po::bool_switch(&options.ignoreCongMarks),
+                      "do not reduce the window after receiving a congestion mark")
+    ("disable-cwa",   po::bool_switch(&options.disableCwa),
+                      "disable Conservative Window Adaptation (reduce the window "
+                      "on each congestion event instead of at most once per RTT)")
+    ("init-cwnd",     po::value<double>(&options.initCwnd)->default_value(options.initCwnd),
+                      "initial congestion window in segments")
+    ("init-ssthresh", po::value<double>(&options.initSsthresh),
+                      "initial slow start threshold in segments (defaults to infinity)")
+    ("rto-alpha", po::value<double>(&rttEstOptions->alpha)->default_value(rttEstOptions->alpha),
+                  "alpha value for RTO calculation")
+    ("rto-beta",  po::value<double>(&rttEstOptions->beta)->default_value(rttEstOptions->beta),
+                  "beta value for RTO calculation")
+    ("rto-k",     po::value<int>(&rttEstOptions->k)->default_value(rttEstOptions->k),
+                  "k value for RTO calculation")
+    ("min-rto",   po::value<time::milliseconds::rep>()->default_value(
+                    time::duration_cast<time::milliseconds>(rttEstOptions->minRto).count()),
+                  "minimum RTO value, in milliseconds")
+    ("max-rto",   po::value<time::milliseconds::rep>()->default_value(
+                    time::duration_cast<time::milliseconds>(rttEstOptions->maxRto).count()),
+                  "maximum RTO value, in milliseconds")
+    ("log-cwnd",  po::value<std::string>(&cwndPath), "log file for congestion window stats")
+    ("log-rtt",   po::value<std::string>(&rttPath), "log file for round-trip time stats")
+    ;
+
+  po::options_description aimdPipeDesc("AIMD pipeline options");
+  aimdPipeDesc.add_options()
+    ("aimd-step", po::value<double>(&options.aiStep)->default_value(options.aiStep),
+                  "additive increase step")
+    ("aimd-beta", po::value<double>(&options.mdCoef)->default_value(options.mdCoef),
+                  "multiplicative decrease factor")
+    ("reset-cwnd-to-init", po::bool_switch(&options.resetCwndToInit),
+                           "after a congestion event, reset the window to the "
+                           "initial value instead of resetting to ssthresh")
+    ;
+
+  po::options_description cubicPipeDesc("CUBIC pipeline options");
+  cubicPipeDesc.add_options()
+    ("cubic-beta", po::value<double>(&options.cubicBeta), "window decrease factor (defaults to 0.7)")
+    ("fast-conv",  po::bool_switch(&options.enableFastConv), "enable fast convergence")
+    ;
+
+  po::options_description visibleDesc;
+  visibleDesc.add(basicDesc)
+             .add(fixedPipeDesc)
+             .add(adaptivePipeDesc)
+             .add(aimdPipeDesc)
+             .add(cubicPipeDesc);
+
+  po::options_description hiddenDesc;
+  hiddenDesc.add_options()
+    ("name", po::value<std::string>(&prefix), "NDN name of the requested content");
+
+  po::options_description optDesc;
+  optDesc.add(visibleDesc).add(hiddenDesc);
+
+  po::positional_options_description p;
+  p.add("name", -1);
+
+  po::variables_map vm;
+  try {
+    po::store(po::command_line_parser(argc, argv).options(optDesc).positional(p).run(), vm);
+    po::notify(vm);
+  }
+  catch (const po::error& e) {
+    std::cerr << "ERROR: " << e.what() << "\n";
+    return 2;
+  }
+  catch (const boost::bad_any_cast& e) {
+    std::cerr << "ERROR: " << e.what() << "\n";
+    return 2;
+  }
+
+  if (vm.count("help") > 0) {
+    std::cout << "Usage: " << programName << " [options] ndn:/name\n";
+    std::cout << visibleDesc;
+    return 0;
+  }
+
+  if (vm.count("version") > 0) {
+    std::cout << "ndnget " << tools::VERSION << "\n";
+    return 0;
+  }
+
+  if (prefix.empty()) {
+    std::cerr << "Usage: " << programName << " [options] ndn:/name\n";
+    std::cerr << visibleDesc;
+    return 2;
+  }
+
+  if (nameConv == "marker" || nameConv == "m" || nameConv == "1") {
+    name::setConventionEncoding(name::Convention::MARKER);
+  }
+  else if (nameConv == "typed" || nameConv == "t" || nameConv == "2") {
+    name::setConventionEncoding(name::Convention::TYPED);
+  }
+  else if (!nameConv.empty()) {
+    std::cerr << "ERROR: '" << nameConv << "' is not a valid naming convention\n";
+    return 2;
+  }
+
+  options.interestLifetime = time::milliseconds(vm["lifetime"].as<time::milliseconds::rep>());
+  if (options.interestLifetime < 0_ms) {
+    std::cerr << "ERROR: --lifetime cannot be negative\n";
+    return 2;
+  }
+
+  if (options.maxRetriesOnTimeoutOrNack < -1 || options.maxRetriesOnTimeoutOrNack > 1024) {
+    std::cerr << "ERROR: --retries must be between -1 and 1024\n";
+    return 2;
+  }
+
+  if (options.isQuiet && options.isVerbose) {
+    std::cerr << "ERROR: cannot be quiet and verbose at the same time\n";
+    return 2;
+  }
+
+  if (options.maxPipelineSize < 1 || options.maxPipelineSize > 1024) {
+    std::cerr << "ERROR: --pipeline-size must be between 1 and 1024\n";
+    return 2;
+  }
+
+  if (rttEstOptions->k < 0) {
+    std::cerr << "ERROR: --rto-k cannot be negative\n";
+    return 2;
+  }
+
+  rttEstOptions->minRto = time::milliseconds(vm["min-rto"].as<time::milliseconds::rep>());
+  if (rttEstOptions->minRto < 0_ms) {
+    std::cerr << "ERROR: --min-rto cannot be negative\n";
+    return 2;
+  }
+
+  rttEstOptions->maxRto = time::milliseconds(vm["max-rto"].as<time::milliseconds::rep>());
+  if (rttEstOptions->maxRto < rttEstOptions->minRto) {
+    std::cerr << "ERROR: --max-rto cannot be smaller than --min-rto\n";
+    return 2;
+  }
+
+  try {
+    Face face;
+    auto discover = std::make_unique<DiscoverVersion>(face, Name(prefix), options);
+    std::unique_ptr<PipelineInterests> pipeline;
+    std::unique_ptr<StatisticsCollector> statsCollector;
+    std::unique_ptr<RttEstimatorWithStats> rttEstimator;
+    std::ofstream statsFileCwnd;
+    std::ofstream statsFileRtt;
+
+    if (pipelineType == "fixed") {
+      pipeline = std::make_unique<PipelineInterestsFixed>(face, options);
+    }
+    else if (pipelineType == "aimd" || pipelineType == "cubic") {
+      if (options.isVerbose) {
+        using namespace ndn::time;
+        std::cerr << "RTT estimator parameters:\n"
+                  << "\tAlpha = " << rttEstOptions->alpha << "\n"
+                  << "\tBeta = " << rttEstOptions->beta << "\n"
+                  << "\tK = " << rttEstOptions->k << "\n"
+                  << "\tInitial RTO = " << duration_cast<milliseconds>(rttEstOptions->initialRto) << "\n"
+                  << "\tMin RTO = " << duration_cast<milliseconds>(rttEstOptions->minRto) << "\n"
+                  << "\tMax RTO = " << duration_cast<milliseconds>(rttEstOptions->maxRto) << "\n"
+                  << "\tBackoff multiplier = " << rttEstOptions->rtoBackoffMultiplier << "\n";
+      }
+      rttEstimator = std::make_unique<RttEstimatorWithStats>(std::move(rttEstOptions));
+
+      std::unique_ptr<PipelineInterestsAdaptive> adaptivePipeline;
+      if (pipelineType == "aimd") {
+        adaptivePipeline = std::make_unique<PipelineInterestsAimd>(face, *rttEstimator, options);
+      }
+      else {
+        adaptivePipeline = std::make_unique<PipelineInterestsCubic>(face, *rttEstimator, options);
+      }
+
+      if (!cwndPath.empty() || !rttPath.empty()) {
+        if (!cwndPath.empty()) {
+          statsFileCwnd.open(cwndPath);
+          if (statsFileCwnd.fail()) {
+            std::cerr << "ERROR: failed to open '" << cwndPath << "'\n";
+            return 4;
+          }
+        }
+        if (!rttPath.empty()) {
+          statsFileRtt.open(rttPath);
+          if (statsFileRtt.fail()) {
+            std::cerr << "ERROR: failed to open '" << rttPath << "'\n";
+            return 4;
+          }
+        }
+        statsCollector = std::make_unique<StatisticsCollector>(*adaptivePipeline, statsFileCwnd, statsFileRtt);
+      }
+
+      pipeline = std::move(adaptivePipeline);
+    }
+    else {
+      std::cerr << "ERROR: '" << pipelineType << "' is not a valid pipeline type\n";
+      return 2;
+    }
+
+    Consumer consumer(security::getAcceptAllValidator());
+    BOOST_ASSERT(discover != nullptr);
+    BOOST_ASSERT(pipeline != nullptr);
+    consumer.run(std::move(discover), std::move(pipeline));
+    face.processEvents();
+  }
+  catch (const Consumer::ApplicationNackError& e) {
+    std::cerr << "ERROR: " << e.what() << "\n";
+    return 3;
+  }
+  catch (const Consumer::DataValidationError& e) {
+    std::cerr << "ERROR: " << e.what() << "\n";
+    return 5;
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << "\n";
+    return 1;
+  }
+
+  return 0;
+}
+
+} // namespace ndn::get
+
+int
+main(int argc, char* argv[])
+{
+  return ndn::get::main(argc, argv);
+}
diff --git a/tools/get/options.hpp b/tools/get/options.hpp
new file mode 100644
index 0000000..5b65540
--- /dev/null
+++ b/tools/get/options.hpp
@@ -0,0 +1,69 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Andrea Tosatto
+ * @author Davide Pesavento
+ */
+
+#ifndef NDN_TOOLS_GET_OPTIONS_HPP
+#define NDN_TOOLS_GET_OPTIONS_HPP
+
+#include <ndn-cxx/interest.hpp>
+#include <ndn-cxx/util/time.hpp>
+
+#include <limits>
+
+namespace ndn::get {
+
+struct Options
+{
+  // Common options
+  time::milliseconds interestLifetime = DEFAULT_INTEREST_LIFETIME;
+  int maxRetriesOnTimeoutOrNack = 15;
+  bool disableVersionDiscovery = false;
+  bool mustBeFresh = false;
+  bool isQuiet = false;
+  bool isVerbose = false;
+
+  // Fixed pipeline options
+  size_t maxPipelineSize = 1;
+
+  // Adaptive pipeline common options
+  double initCwnd = 2.0;        ///< initial congestion window size
+  double initSsthresh = std::numeric_limits<double>::max(); ///< initial slow start threshold
+  time::milliseconds rtoCheckInterval{10}; ///< interval for checking retransmission timer
+  bool ignoreCongMarks = false; ///< disable window decrease after receiving congestion mark
+  bool disableCwa = false;      ///< disable conservative window adaptation
+
+  // AIMD pipeline options
+  double aiStep = 1.0;          ///< AIMD additive increase step (in segments)
+  double mdCoef = 0.5;          ///< AIMD multiplicative decrease factor
+  bool resetCwndToInit = false; ///< reduce cwnd to initCwnd when loss event occurs
+
+  // Cubic pipeline options
+  double cubicBeta = 0.7;       ///< cubic multiplicative decrease factor
+  bool enableFastConv = false;  ///< use cubic fast convergence
+};
+
+} // namespace ndn::get
+
+#endif // NDN_TOOLS_GET_OPTIONS_HPP
diff --git a/tools/get/pipeline-interests-adaptive.cpp b/tools/get/pipeline-interests-adaptive.cpp
new file mode 100644
index 0000000..96949ef
--- /dev/null
+++ b/tools/get/pipeline-interests-adaptive.cpp
@@ -0,0 +1,461 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Shuo Yang
+ * @author Weiwei Liu
+ * @author Chavoosh Ghasemi
+ * @author Klaus Schneider
+ */
+
+#include "pipeline-interests-adaptive.hpp"
+#include "data-fetcher.hpp"
+
+#include <boost/lexical_cast.hpp>
+#include <iomanip>
+#include <iostream>
+
+namespace ndn::get {
+
+PipelineInterestsAdaptive::PipelineInterestsAdaptive(Face& face,
+                                                     RttEstimatorWithStats& rttEstimator,
+                                                     const Options& opts)
+  : PipelineInterests(face, opts)
+  , m_cwnd(m_options.initCwnd)
+  , m_ssthresh(m_options.initSsthresh)
+  , m_rttEstimator(rttEstimator)
+  , m_scheduler(m_face.getIoContext())
+{
+}
+
+PipelineInterestsAdaptive::~PipelineInterestsAdaptive()
+{
+  cancel();
+}
+
+void
+PipelineInterestsAdaptive::doRun()
+{
+  if (allSegmentsReceived()) {
+    cancel();
+    if (!m_options.isQuiet) {
+      printSummary();
+    }
+    return;
+  }
+
+  // schedule the event to check retransmission timer
+  m_checkRtoEvent = m_scheduler.schedule(m_options.rtoCheckInterval, [this] { checkRto(); });
+
+  schedulePackets();
+}
+
+void
+PipelineInterestsAdaptive::doCancel()
+{
+  m_checkRtoEvent.cancel();
+  m_segmentInfo.clear();
+}
+
+void
+PipelineInterestsAdaptive::checkRto()
+{
+  if (isStopping())
+    return;
+
+  bool hasTimeout = false;
+  uint64_t highTimeoutSeg = 0;
+
+  for (auto& entry : m_segmentInfo) {
+    SegmentInfo& segInfo = entry.second;
+    if (segInfo.state != SegmentState::InRetxQueue) { // skip segments already in the retx queue
+      auto timeElapsed = time::steady_clock::now() - segInfo.timeSent;
+      if (timeElapsed > segInfo.rto) { // timer expired?
+        m_nTimeouts++;
+        hasTimeout = true;
+        highTimeoutSeg = std::max(highTimeoutSeg, entry.first);
+        enqueueForRetransmission(entry.first);
+      }
+    }
+  }
+
+  if (hasTimeout) {
+    recordTimeout(highTimeoutSeg);
+    schedulePackets();
+  }
+
+  // schedule the next check after predefined interval
+  m_checkRtoEvent = m_scheduler.schedule(m_options.rtoCheckInterval, [this] { checkRto(); });
+}
+
+void
+PipelineInterestsAdaptive::sendInterest(uint64_t segNo, bool isRetransmission)
+{
+  if (isStopping())
+    return;
+
+  if (m_hasFinalBlockId && segNo > m_lastSegmentNo)
+    return;
+
+  if (!isRetransmission && m_hasFailure)
+    return;
+
+  if (m_options.isVerbose) {
+    std::cerr << (isRetransmission ? "Retransmitting" : "Requesting")
+              << " segment #" << segNo << "\n";
+  }
+
+  if (isRetransmission) {
+    // keep track of retx count for this segment
+    auto ret = m_retxCount.emplace(segNo, 1);
+    if (!ret.second) { // not the first retransmission
+      m_retxCount[segNo] += 1;
+      if (m_options.maxRetriesOnTimeoutOrNack != DataFetcher::MAX_RETRIES_INFINITE &&
+          m_retxCount[segNo] > m_options.maxRetriesOnTimeoutOrNack) {
+        return handleFail(segNo, "Reached the maximum number of retries (" +
+                          std::to_string(m_options.maxRetriesOnTimeoutOrNack) +
+                          ") while retrieving segment #" + std::to_string(segNo));
+      }
+
+      if (m_options.isVerbose) {
+        std::cerr << "# of retries for segment #" << segNo
+                  << " is " << m_retxCount[segNo] << "\n";
+      }
+    }
+  }
+
+  auto interest = Interest()
+                  .setName(Name(m_prefix).appendSegment(segNo))
+                  .setMustBeFresh(m_options.mustBeFresh)
+                  .setInterestLifetime(m_options.interestLifetime);
+
+  SegmentInfo& segInfo = m_segmentInfo[segNo];
+  segInfo.interestHdl = m_face.expressInterest(interest,
+                                               FORWARD_TO_MEM_FN(handleData),
+                                               FORWARD_TO_MEM_FN(handleNack),
+                                               FORWARD_TO_MEM_FN(handleLifetimeExpiration));
+  segInfo.timeSent = time::steady_clock::now();
+  segInfo.rto = m_rttEstimator.getEstimatedRto();
+
+  m_nInFlight++;
+  m_nSent++;
+
+  if (isRetransmission) {
+    segInfo.state = SegmentState::Retransmitted;
+    m_nRetransmitted++;
+  }
+  else {
+    m_highInterest = segNo;
+    segInfo.state = SegmentState::FirstTimeSent;
+  }
+}
+
+void
+PipelineInterestsAdaptive::schedulePackets()
+{
+  BOOST_ASSERT(m_nInFlight >= 0);
+  auto availableWindowSize = static_cast<int64_t>(m_cwnd) - m_nInFlight;
+
+  while (availableWindowSize > 0) {
+    if (!m_retxQueue.empty()) { // do retransmission first
+      uint64_t retxSegNo = m_retxQueue.front();
+      m_retxQueue.pop();
+      if (m_segmentInfo.count(retxSegNo) == 0) {
+        m_nSkippedRetx++;
+        continue;
+      }
+      // the segment is still in the map, that means it needs to be retransmitted
+      sendInterest(retxSegNo, true);
+    }
+    else { // send next segment
+      sendInterest(getNextSegmentNo(), false);
+    }
+    availableWindowSize--;
+  }
+}
+
+void
+PipelineInterestsAdaptive::handleData(const Interest& interest, const Data& data)
+{
+  if (isStopping())
+    return;
+
+  // Interest was expressed with CanBePrefix=false
+  BOOST_ASSERT(data.getName().equals(interest.getName()));
+
+  if (!m_hasFinalBlockId && data.getFinalBlock()) {
+    m_lastSegmentNo = data.getFinalBlock()->toSegment();
+    m_hasFinalBlockId = true;
+    cancelInFlightSegmentsGreaterThan(m_lastSegmentNo);
+    if (m_hasFailure && m_lastSegmentNo >= m_failedSegNo) {
+      // previously failed segment is part of the content
+      return onFailure(m_failureReason);
+    }
+    else {
+      m_hasFailure = false;
+    }
+  }
+
+  uint64_t recvSegNo = getSegmentFromPacket(data);
+  auto segIt = m_segmentInfo.find(recvSegNo);
+  if (segIt == m_segmentInfo.end()) {
+    return; // ignore already-received segment
+  }
+
+  SegmentInfo& segInfo = segIt->second;
+  time::nanoseconds rtt = time::steady_clock::now() - segInfo.timeSent;
+  if (m_options.isVerbose) {
+    std::cerr << "Received segment #" << recvSegNo
+              << ", rtt=" << rtt.count() / 1e6 << "ms"
+              << ", rto=" << segInfo.rto.count() / 1e6 << "ms\n";
+  }
+
+  m_highData = std::max(m_highData, recvSegNo);
+
+  // for segments in retx queue, we must not decrement m_nInFlight
+  // because it was already decremented when the segment timed out
+  if (segInfo.state != SegmentState::InRetxQueue) {
+    m_nInFlight--;
+  }
+
+  // upon finding congestion mark, decrease the window size
+  // without retransmitting any packet
+  if (data.getCongestionMark() > 0) {
+    m_nCongMarks++;
+    if (!m_options.ignoreCongMarks) {
+      if (m_options.disableCwa || m_highData > m_recPoint) {
+        m_recPoint = m_highInterest;  // react to only one congestion event (timeout or congestion mark)
+                                      // per RTT (conservative window adaptation)
+        m_nMarkDecr++;
+        decreaseWindow();
+
+        if (m_options.isVerbose) {
+          std::cerr << "Received congestion mark, value = " << data.getCongestionMark()
+                    << ", new cwnd = " << m_cwnd << "\n";
+        }
+      }
+    }
+    else {
+      increaseWindow();
+    }
+  }
+  else {
+    increaseWindow();
+  }
+
+  onData(data);
+
+  // do not sample RTT for retransmitted segments
+  if ((segInfo.state == SegmentState::FirstTimeSent ||
+       segInfo.state == SegmentState::InRetxQueue) &&
+      m_retxCount.count(recvSegNo) == 0) {
+    auto nExpectedSamples = std::max<int64_t>((m_nInFlight + 1) >> 1, 1);
+    BOOST_ASSERT(nExpectedSamples > 0);
+    m_rttEstimator.addMeasurement(rtt, static_cast<size_t>(nExpectedSamples));
+    afterRttMeasurement({recvSegNo, rtt,
+                         m_rttEstimator.getSmoothedRtt(),
+                         m_rttEstimator.getRttVariation(),
+                         m_rttEstimator.getEstimatedRto()});
+  }
+
+  // remove the entry associated with the received segment
+  m_segmentInfo.erase(segIt);
+
+  if (allSegmentsReceived()) {
+    cancel();
+    if (!m_options.isQuiet) {
+      printSummary();
+    }
+  }
+  else {
+    schedulePackets();
+  }
+}
+
+void
+PipelineInterestsAdaptive::handleNack(const Interest& interest, const lp::Nack& nack)
+{
+  if (isStopping())
+    return;
+
+  if (m_options.isVerbose)
+    std::cerr << "Received Nack with reason " << nack.getReason()
+              << " for Interest " << interest << "\n";
+
+  uint64_t segNo = getSegmentFromPacket(interest);
+
+  switch (nack.getReason()) {
+    case lp::NackReason::DUPLICATE:
+      // ignore duplicates
+      break;
+    case lp::NackReason::CONGESTION:
+      // treated the same as timeout for now
+      enqueueForRetransmission(segNo);
+      recordTimeout(segNo);
+      schedulePackets();
+      break;
+    default:
+      handleFail(segNo, "Could not retrieve data for " + interest.getName().toUri() +
+                 ", reason: " + boost::lexical_cast<std::string>(nack.getReason()));
+      break;
+  }
+}
+
+void
+PipelineInterestsAdaptive::handleLifetimeExpiration(const Interest& interest)
+{
+  if (isStopping())
+    return;
+
+  m_nTimeouts++;
+
+  uint64_t segNo = getSegmentFromPacket(interest);
+  enqueueForRetransmission(segNo);
+  recordTimeout(segNo);
+  schedulePackets();
+}
+
+void
+PipelineInterestsAdaptive::recordTimeout(uint64_t segNo)
+{
+  if (m_options.disableCwa || segNo > m_recPoint) {
+    // interests that are still outstanding during a timeout event
+    // should not trigger another window decrease later (bug #5202)
+    m_recPoint = m_highInterest;
+
+    decreaseWindow();
+    m_rttEstimator.backoffRto();
+    m_nLossDecr++;
+
+    if (m_options.isVerbose) {
+      std::cerr << "Packet loss event, new cwnd = " << m_cwnd
+                << ", ssthresh = " << m_ssthresh << "\n";
+    }
+  }
+}
+
+void
+PipelineInterestsAdaptive::enqueueForRetransmission(uint64_t segNo)
+{
+  BOOST_ASSERT(m_nInFlight > 0);
+  m_nInFlight--;
+  m_retxQueue.push(segNo);
+  m_segmentInfo.at(segNo).state = SegmentState::InRetxQueue;
+}
+
+void
+PipelineInterestsAdaptive::handleFail(uint64_t segNo, const std::string& reason)
+{
+  if (isStopping())
+    return;
+
+  // if the failed segment is definitely part of the content, raise a fatal error
+  if (m_hasFinalBlockId && segNo <= m_lastSegmentNo)
+    return onFailure(reason);
+
+  if (!m_hasFinalBlockId) {
+    m_segmentInfo.erase(segNo);
+    m_nInFlight--;
+
+    if (m_segmentInfo.empty()) {
+      onFailure("Fetching terminated but no final segment number has been found");
+    }
+    else {
+      cancelInFlightSegmentsGreaterThan(segNo);
+      m_hasFailure = true;
+      m_failedSegNo = segNo;
+      m_failureReason = reason;
+    }
+  }
+}
+
+void
+PipelineInterestsAdaptive::cancelInFlightSegmentsGreaterThan(uint64_t segNo)
+{
+  for (auto it = m_segmentInfo.begin(); it != m_segmentInfo.end();) {
+    // cancel fetching all segments that follow
+    if (it->first > segNo) {
+      it = m_segmentInfo.erase(it);
+      m_nInFlight--;
+    }
+    else {
+      ++it;
+    }
+  }
+}
+
+void
+PipelineInterestsAdaptive::printOptions() const
+{
+  PipelineInterests::printOptions();
+  std::cerr
+      << "\tInitial congestion window size = " << m_options.initCwnd << "\n"
+      << "\tInitial slow start threshold = " << m_options.initSsthresh << "\n"
+      << "\tAdditive increase step = " << m_options.aiStep << "\n"
+      << "\tMultiplicative decrease factor = " << m_options.mdCoef << "\n"
+      << "\tRTO check interval = " << m_options.rtoCheckInterval << "\n"
+      << "\tReact to congestion marks = " << (m_options.ignoreCongMarks ? "no" : "yes") << "\n"
+      << "\tConservative window adaptation = " << (m_options.disableCwa ? "no" : "yes") << "\n"
+      << "\tResetting window to " << (m_options.resetCwndToInit ?
+                                        "initial value" : "ssthresh") << " upon loss event\n";
+}
+
+void
+PipelineInterestsAdaptive::printSummary() const
+{
+  PipelineInterests::printSummary();
+  std::cerr << "Congestion marks: " << m_nCongMarks << " (caused " << m_nMarkDecr << " window decreases)\n"
+            << "Timeouts: " << m_nTimeouts << " (caused " << m_nLossDecr << " window decreases)\n"
+            << "Retransmitted segments: " << m_nRetransmitted
+            << " (" << (m_nSent == 0 ? 0 : (m_nRetransmitted * 100.0 / m_nSent)) << "%)"
+            << ", skipped: " << m_nSkippedRetx << "\n"
+            << "RTT ";
+
+  if (m_rttEstimator.getMinRtt() == time::nanoseconds::max() ||
+      m_rttEstimator.getMaxRtt() == time::nanoseconds::min()) {
+    std::cerr << "stats unavailable\n";
+  }
+  else {
+    std::cerr << "min/avg/max = " << std::fixed << std::setprecision(3)
+              << m_rttEstimator.getMinRtt().count() / 1e6 << "/"
+              << m_rttEstimator.getAvgRtt().count() / 1e6 << "/"
+              << m_rttEstimator.getMaxRtt().count() / 1e6 << " ms\n";
+  }
+}
+
+std::ostream&
+operator<<(std::ostream& os, SegmentState state)
+{
+  switch (state) {
+  case SegmentState::FirstTimeSent:
+    os << "FirstTimeSent";
+    break;
+  case SegmentState::InRetxQueue:
+    os << "InRetxQueue";
+    break;
+  case SegmentState::Retransmitted:
+    os << "Retransmitted";
+    break;
+  }
+  return os;
+}
+
+} // namespace ndn::get
diff --git a/tools/get/pipeline-interests-adaptive.hpp b/tools/get/pipeline-interests-adaptive.hpp
new file mode 100644
index 0000000..23e1138
--- /dev/null
+++ b/tools/get/pipeline-interests-adaptive.hpp
@@ -0,0 +1,231 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Shuo Yang
+ * @author Weiwei Liu
+ * @author Chavoosh Ghasemi
+ * @author Klaus Schneider
+ */
+
+#ifndef NDN_TOOLS_GET_PIPELINE_INTERESTS_ADAPTIVE_HPP
+#define NDN_TOOLS_GET_PIPELINE_INTERESTS_ADAPTIVE_HPP
+
+#include "pipeline-interests.hpp"
+
+#include <ndn-cxx/util/rtt-estimator.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
+#include <ndn-cxx/util/signal.hpp>
+
+#include <queue>
+#include <unordered_map>
+
+namespace ndn::get {
+
+using util::RttEstimatorWithStats;
+
+/**
+ * @brief indicates the state of the segment
+ */
+enum class SegmentState {
+  FirstTimeSent, ///< segment has been sent for the first time
+  InRetxQueue,   ///< segment is in retransmission queue
+  Retransmitted, ///< segment has been retransmitted
+};
+
+std::ostream&
+operator<<(std::ostream& os, SegmentState state);
+
+/**
+ * @brief Wraps up information that's necessary for segment transmission
+ */
+struct SegmentInfo
+{
+  ScopedPendingInterestHandle interestHdl;
+  time::steady_clock::time_point timeSent;
+  time::nanoseconds rto;
+  SegmentState state;
+};
+
+/**
+ * @brief Service for retrieving Data via an Interest pipeline
+ *
+ * Retrieves all segmented Data under the specified prefix by maintaining a dynamic
+ * congestion window combined with a Conservative Loss Adaptation algorithm. For details,
+ * please refer to the description in section "Interest pipeline types in ndnget" of
+ * tools/get/README.md
+ *
+ * Provides retrieved Data on arrival with no ordering guarantees. Data is delivered to the
+ * PipelineInterests' user via callback immediately upon arrival.
+ */
+class PipelineInterestsAdaptive : public PipelineInterests
+{
+public:
+  /**
+   * @brief Constructor.
+   *
+   * Configures the pipelining service without specifying the retrieval namespace. After this
+   * configuration the method run must be called to start the Pipeline.
+   */
+  PipelineInterestsAdaptive(Face& face, RttEstimatorWithStats& rttEstimator, const Options& opts);
+
+  ~PipelineInterestsAdaptive() override;
+
+  /**
+   * @brief Signals when the congestion window changes.
+   *
+   * The callback function should be: `void(nanoseconds age, double cwnd)`, where `age` is the
+   * time since the pipeline started and `cwnd` is the new congestion window size (in segments).
+   */
+  signal::Signal<PipelineInterestsAdaptive, time::nanoseconds, double> afterCwndChange;
+
+  struct RttSample
+  {
+    uint64_t segNum;          ///< segment number on which this sample was taken
+    time::nanoseconds rtt;    ///< measured RTT
+    time::nanoseconds sRtt;   ///< smoothed RTT
+    time::nanoseconds rttVar; ///< RTT variation
+    time::nanoseconds rto;    ///< retransmission timeout
+  };
+
+  /**
+   * @brief Signals when a new RTT sample has been taken.
+   */
+  signal::Signal<PipelineInterestsAdaptive, RttSample> afterRttMeasurement;
+
+protected:
+  DECLARE_SIGNAL_EMIT(afterCwndChange)
+
+  void
+  printOptions() const;
+
+private:
+  /**
+   * @brief Increase congestion window.
+   */
+  virtual void
+  increaseWindow() = 0;
+
+  /**
+   * @brief Decrease congestion window.
+   */
+  virtual void
+  decreaseWindow() = 0;
+
+private:
+  /**
+   * @brief Fetch all the segments between 0 and lastSegment of the specified prefix.
+   *
+   * Starts the pipeline with an adaptive window algorithm to control the window size.
+   * The pipeline will fetch every segment until the last segment is successfully received
+   * or an error occurs.
+   */
+  void
+  doRun() final;
+
+  /**
+   * @brief Stop all fetch operations.
+   */
+  void
+  doCancel() final;
+
+  /**
+   * @brief Check RTO for all sent-but-not-acked segments.
+   */
+  void
+  checkRto();
+
+  /**
+   * @param segNo the segment # of the to-be-sent Interest
+   * @param isRetransmission true if this is a retransmission
+   */
+  void
+  sendInterest(uint64_t segNo, bool isRetransmission);
+
+  void
+  schedulePackets();
+
+  void
+  handleData(const Interest& interest, const Data& data);
+
+  void
+  handleNack(const Interest& interest, const lp::Nack& nack);
+
+  void
+  handleLifetimeExpiration(const Interest& interest);
+
+  void
+  recordTimeout(uint64_t segNo);
+
+  void
+  enqueueForRetransmission(uint64_t segNo);
+
+  void
+  handleFail(uint64_t segNo, const std::string& reason);
+
+  void
+  cancelInFlightSegmentsGreaterThan(uint64_t segNo);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  void
+  printSummary() const final;
+
+PUBLIC_WITH_TESTS_ELSE_PROTECTED:
+  static constexpr double MIN_SSTHRESH = 2.0;
+
+  double m_cwnd; ///< current congestion window size (in segments)
+  double m_ssthresh; ///< current slow start threshold
+  RttEstimatorWithStats& m_rttEstimator;
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  Scheduler m_scheduler;
+  scheduler::ScopedEventId m_checkRtoEvent;
+
+  uint64_t m_highData = 0; ///< the highest segment number of the Data packet the consumer has received so far
+  uint64_t m_highInterest = 0; ///< the highest segment number of the Interests the consumer has sent so far
+  uint64_t m_recPoint = 0; ///< the value of m_highInterest when a packet loss event occurred,
+                           ///< it remains fixed until the next packet loss event happens
+
+  int64_t m_nInFlight = 0; ///< # of segments in flight
+  int64_t m_nLossDecr = 0; ///< # of window decreases caused by packet loss
+  int64_t m_nMarkDecr = 0; ///< # of window decreases caused by congestion marks
+  int64_t m_nTimeouts = 0; ///< # of timed out segments
+  int64_t m_nSkippedRetx = 0; ///< # of segments queued for retransmission but received before the
+                              ///< retransmission occurred
+  int64_t m_nRetransmitted = 0; ///< # of retransmitted segments
+  int64_t m_nCongMarks = 0; ///< # of data packets with congestion mark
+  int64_t m_nSent = 0; ///< # of interest packets sent out (including retransmissions)
+
+  std::unordered_map<uint64_t, SegmentInfo> m_segmentInfo; ///< keeps all the internal information
+                                                           ///< on sent but not acked segments
+  std::unordered_map<uint64_t, int> m_retxCount; ///< maps segment number to its retransmission count;
+                                                 ///< if the count reaches to the maximum number of
+                                                 ///< timeout/nack retries, the pipeline will be aborted
+  std::queue<uint64_t> m_retxQueue;
+
+  bool m_hasFailure = false;
+  uint64_t m_failedSegNo = 0;
+  std::string m_failureReason;
+};
+
+} // namespace ndn::get
+
+#endif // NDN_TOOLS_GET_PIPELINE_INTERESTS_ADAPTIVE_HPP
diff --git a/tools/get/pipeline-interests-aimd.cpp b/tools/get/pipeline-interests-aimd.cpp
new file mode 100644
index 0000000..37beb58
--- /dev/null
+++ b/tools/get/pipeline-interests-aimd.cpp
@@ -0,0 +1,67 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Shuo Yang
+ * @author Weiwei Liu
+ * @author Chavoosh Ghasemi
+ * @author Klaus Schneider
+ */
+
+#include "pipeline-interests-aimd.hpp"
+
+#include <cmath>
+
+namespace ndn::get {
+
+PipelineInterestsAimd::PipelineInterestsAimd(Face& face, RttEstimatorWithStats& rttEstimator,
+                                             const Options& opts)
+  : PipelineInterestsAdaptive(face, rttEstimator, opts)
+{
+  if (m_options.isVerbose) {
+    printOptions();
+  }
+}
+
+void
+PipelineInterestsAimd::increaseWindow()
+{
+  if (m_cwnd < m_ssthresh) {
+    m_cwnd += m_options.aiStep; // additive increase
+  }
+  else {
+    m_cwnd += m_options.aiStep / std::floor(m_cwnd); // congestion avoidance
+  }
+
+  emitSignal(afterCwndChange, time::steady_clock::now() - getStartTime(), m_cwnd);
+}
+
+void
+PipelineInterestsAimd::decreaseWindow()
+{
+  // please refer to RFC 5681, Section 3.1 for the rationale behind it
+  m_ssthresh = std::max(MIN_SSTHRESH, m_cwnd * m_options.mdCoef); // multiplicative decrease
+  m_cwnd = m_options.resetCwndToInit ? m_options.initCwnd : m_ssthresh;
+
+  emitSignal(afterCwndChange, time::steady_clock::now() - getStartTime(), m_cwnd);
+}
+
+} // namespace ndn::get
diff --git a/tools/get/pipeline-interests-aimd.hpp b/tools/get/pipeline-interests-aimd.hpp
new file mode 100644
index 0000000..858db87
--- /dev/null
+++ b/tools/get/pipeline-interests-aimd.hpp
@@ -0,0 +1,54 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Shuo Yang
+ * @author Weiwei Liu
+ * @author Chavoosh Ghasemi
+ * @author Klaus Schneider
+ */
+
+#ifndef NDN_TOOLS_GET_PIPELINE_INTERESTS_AIMD_HPP
+#define NDN_TOOLS_GET_PIPELINE_INTERESTS_AIMD_HPP
+
+#include "pipeline-interests-adaptive.hpp"
+
+namespace ndn::get {
+
+/**
+ * @brief Implements AIMD window increase and decrease.
+ */
+class PipelineInterestsAimd final : public PipelineInterestsAdaptive
+{
+public:
+  PipelineInterestsAimd(Face& face, RttEstimatorWithStats& rttEstimator, const Options& opts);
+
+private:
+  void
+  increaseWindow() final;
+
+  void
+  decreaseWindow() final;
+};
+
+} // namespace ndn::get
+
+#endif // NDN_TOOLS_GET_PIPELINE_INTERESTS_AIMD_HPP
diff --git a/tools/get/pipeline-interests-cubic.cpp b/tools/get/pipeline-interests-cubic.cpp
new file mode 100644
index 0000000..a74e602
--- /dev/null
+++ b/tools/get/pipeline-interests-cubic.cpp
@@ -0,0 +1,114 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Klaus Schneider
+ */
+
+#include "pipeline-interests-cubic.hpp"
+
+#include <cmath>
+#include <iostream>
+
+namespace ndn::get {
+
+constexpr double CUBIC_C = 0.4;
+
+PipelineInterestsCubic::PipelineInterestsCubic(Face& face, RttEstimatorWithStats& rttEstimator,
+                                               const Options& opts)
+  : PipelineInterestsAdaptive(face, rttEstimator, opts)
+  , m_lastDecrease(time::steady_clock::now())
+{
+  if (m_options.isVerbose) {
+    printOptions();
+    std::cerr << "\tCubic beta = " << m_options.cubicBeta << "\n"
+              << "\tFast convergence = " << (m_options.enableFastConv ? "yes" : "no") << "\n";
+  }
+}
+
+void
+PipelineInterestsCubic::increaseWindow()
+{
+  // Slow start phase
+  if (m_cwnd < m_ssthresh) {
+    m_cwnd += 1.0;
+  }
+  // Congestion avoidance phase
+  else {
+    // If wmax is still 0, set it to the current cwnd. Usually unnecessary,
+    // if m_ssthresh is large enough.
+    if (m_wmax < m_options.initCwnd) {
+      m_wmax = m_cwnd;
+    }
+
+    // 1. Time since last congestion event in seconds
+    const double t = (time::steady_clock::now() - m_lastDecrease).count() / 1e9;
+
+    // 2. Time it takes to increase the window to m_wmax = the cwnd right before the last
+    // window decrease.
+    // K = cubic_root(wmax*(1-beta_cubic)/C) (Eq. 2)
+    const double k = std::cbrt(m_wmax * (1 - m_options.cubicBeta) / CUBIC_C);
+
+    // 3. Target: W_cubic(t) = C*(t-K)^3 + wmax (Eq. 1)
+    const double wCubic = CUBIC_C * std::pow(t - k, 3) + m_wmax;
+
+    // 4. Estimate of Reno Increase (Eq. 4)
+    const double rtt = m_rttEstimator.getSmoothedRtt().count() / 1e9;
+    const double wEst = m_wmax * m_options.cubicBeta +
+                        (3 * (1 - m_options.cubicBeta) / (1 + m_options.cubicBeta)) * (t / rtt);
+
+    // Actual adaptation
+    double cubicIncrement = std::max(wCubic, wEst) - m_cwnd;
+    // Cubic increment must be positive
+    // Note: This change is not part of the RFC, but I added it to improve performance.
+    cubicIncrement = std::max(0.0, cubicIncrement);
+
+    m_cwnd += cubicIncrement / m_cwnd;
+  }
+
+  emitSignal(afterCwndChange, time::steady_clock::now() - getStartTime(), m_cwnd);
+}
+
+void
+PipelineInterestsCubic::decreaseWindow()
+{
+  // A flow remembers the last value of wmax,
+  // before it updates wmax for the current congestion event.
+
+  // Current wmax < last_wmax
+  if (m_options.enableFastConv && m_cwnd < m_lastWmax) {
+    m_lastWmax = m_cwnd;
+    m_wmax = m_cwnd * (1.0 + m_options.cubicBeta) / 2.0;
+  }
+  else {
+    // Save old cwnd as wmax
+    m_lastWmax = m_cwnd;
+    m_wmax = m_cwnd;
+  }
+
+  m_ssthresh = std::max(m_options.initCwnd, m_cwnd * m_options.cubicBeta);
+  m_cwnd = m_ssthresh;
+  m_lastDecrease = time::steady_clock::now();
+
+  emitSignal(afterCwndChange, time::steady_clock::now() - getStartTime(), m_cwnd);
+}
+
+} // namespace ndn::get
diff --git a/tools/get/pipeline-interests-cubic.hpp b/tools/get/pipeline-interests-cubic.hpp
new file mode 100644
index 0000000..8451fd3
--- /dev/null
+++ b/tools/get/pipeline-interests-cubic.hpp
@@ -0,0 +1,59 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Klaus Schneider
+ */
+
+#ifndef NDN_TOOLS_GET_PIPELINE_INTERESTS_CUBIC_HPP
+#define NDN_TOOLS_GET_PIPELINE_INTERESTS_CUBIC_HPP
+
+#include "pipeline-interests-adaptive.hpp"
+
+namespace ndn::get {
+
+/**
+ * @brief Implements Cubic window increase and decrease.
+ *
+ * This implementation follows the RFC8312 https://tools.ietf.org/html/rfc8312
+ * and the Linux kernel implementation https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_cubic.c
+ */
+class PipelineInterestsCubic final : public PipelineInterestsAdaptive
+{
+public:
+  PipelineInterestsCubic(Face& face, RttEstimatorWithStats& rttEstimator, const Options& opts);
+
+private:
+  void
+  increaseWindow() final;
+
+  void
+  decreaseWindow() final;
+
+private:
+  double m_wmax = 0.0; ///< window size before last window decrease
+  double m_lastWmax = 0.0; ///< last wmax
+  time::steady_clock::time_point m_lastDecrease; ///< time of last window decrease
+};
+
+} // namespace ndn::get
+
+#endif // NDN_TOOLS_GET_PIPELINE_INTERESTS_CUBIC_HPP
diff --git a/tools/get/pipeline-interests-fixed.cpp b/tools/get/pipeline-interests-fixed.cpp
new file mode 100644
index 0000000..4d26a04
--- /dev/null
+++ b/tools/get/pipeline-interests-fixed.cpp
@@ -0,0 +1,197 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Wentao Shang
+ * @author Steve DiBenedetto
+ * @author Andrea Tosatto
+ * @author Davide Pesavento
+ * @author Chavoosh Ghasemi
+ */
+
+#include "pipeline-interests-fixed.hpp"
+#include "data-fetcher.hpp"
+
+#include <iostream>
+
+namespace ndn::get {
+
+PipelineInterestsFixed::PipelineInterestsFixed(Face& face, const Options& opts)
+  : PipelineInterests(face, opts)
+{
+  m_segmentFetchers.resize(m_options.maxPipelineSize);
+
+  if (m_options.isVerbose) {
+    printOptions();
+    std::cerr << "\tPipeline size = " << m_options.maxPipelineSize << "\n";
+  }
+}
+
+PipelineInterestsFixed::~PipelineInterestsFixed()
+{
+  cancel();
+}
+
+void
+PipelineInterestsFixed::doRun()
+{
+  // if the FinalBlockId is unknown, this could potentially request non-existent segments
+  for (size_t nRequestedSegments = 0;
+       nRequestedSegments < m_options.maxPipelineSize;
+       ++nRequestedSegments) {
+    if (!fetchNextSegment(nRequestedSegments))
+      // all segments have been requested
+      break;
+  }
+}
+
+bool
+PipelineInterestsFixed::fetchNextSegment(std::size_t pipeNo)
+{
+  if (isStopping())
+    return false;
+
+  if (m_hasFailure) {
+    onFailure("Fetching terminated but no final segment number has been found");
+    return false;
+  }
+
+  uint64_t nextSegmentNo = getNextSegmentNo();
+  if (m_hasFinalBlockId && nextSegmentNo > m_lastSegmentNo)
+    return false;
+
+  // send interest for next segment
+  if (m_options.isVerbose)
+    std::cerr << "Requesting segment #" << nextSegmentNo << "\n";
+
+  auto interest = Interest()
+                  .setName(Name(m_prefix).appendSegment(nextSegmentNo))
+                  .setMustBeFresh(m_options.mustBeFresh)
+                  .setInterestLifetime(m_options.interestLifetime);
+
+  auto fetcher = DataFetcher::fetch(m_face, interest,
+                                    m_options.maxRetriesOnTimeoutOrNack,
+                                    m_options.maxRetriesOnTimeoutOrNack,
+                                    [this, pipeNo] (const auto& interest, const auto& data) {
+                                      handleData(interest, data, pipeNo);
+                                    },
+                                    [this, pipeNo] (const auto&, const auto& reason) {
+                                      handleFail(reason, pipeNo);
+                                    },
+                                    [this, pipeNo] (const auto&, const auto& reason) {
+                                      handleFail(reason, pipeNo);
+                                    },
+                                    m_options.isVerbose);
+
+  BOOST_ASSERT(!m_segmentFetchers[pipeNo].first || !m_segmentFetchers[pipeNo].first->isRunning());
+  m_segmentFetchers[pipeNo] = make_pair(fetcher, nextSegmentNo);
+
+  return true;
+}
+
+void
+PipelineInterestsFixed::doCancel()
+{
+  for (auto& fetcher : m_segmentFetchers) {
+    if (fetcher.first)
+      fetcher.first->cancel();
+  }
+
+  m_segmentFetchers.clear();
+}
+
+void
+PipelineInterestsFixed::handleData(const Interest& interest, const Data& data, size_t pipeNo)
+{
+  if (isStopping())
+    return;
+
+  // Interest was expressed with CanBePrefix=false
+  BOOST_ASSERT(data.getName().equals(interest.getName()));
+
+  if (m_options.isVerbose)
+    std::cerr << "Received segment #" << getSegmentFromPacket(data) << "\n";
+
+  onData(data);
+
+  if (!m_hasFinalBlockId && data.getFinalBlock()) {
+    m_lastSegmentNo = data.getFinalBlock()->toSegment();
+    m_hasFinalBlockId = true;
+
+    for (auto& fetcher : m_segmentFetchers) {
+      if (fetcher.first == nullptr)
+        continue;
+
+      if (fetcher.second > m_lastSegmentNo) {
+        // stop trying to fetch segments that are beyond m_lastSegmentNo
+        fetcher.first->cancel();
+      }
+      else if (fetcher.first->hasError()) { // fetcher.second <= m_lastSegmentNo
+        // there was an error while fetching a segment that is part of the content
+        return onFailure("Failure retrieving segment #" + std::to_string(fetcher.second));
+      }
+    }
+  }
+
+  if (allSegmentsReceived()) {
+    if (!m_options.isQuiet) {
+      printSummary();
+    }
+  }
+  else {
+    fetchNextSegment(pipeNo);
+  }
+}
+
+void PipelineInterestsFixed::handleFail(const std::string& reason, std::size_t pipeNo)
+{
+  if (isStopping())
+    return;
+
+  // if the failed segment is definitely part of the content, raise a fatal error
+  if (m_hasFinalBlockId && m_segmentFetchers[pipeNo].second <= m_lastSegmentNo)
+    return onFailure(reason);
+
+  if (!m_hasFinalBlockId) {
+    bool areAllFetchersStopped = true;
+    for (auto& fetcher : m_segmentFetchers) {
+      if (fetcher.first == nullptr)
+        continue;
+
+      // cancel fetching all segments that follow
+      if (fetcher.second > m_segmentFetchers[pipeNo].second) {
+        fetcher.first->cancel();
+      }
+      else if (fetcher.first->isRunning()) { // fetcher.second <= m_segmentFetchers[pipeNo].second
+        areAllFetchersStopped = false;
+      }
+    }
+
+    if (areAllFetchersStopped) {
+      onFailure("Fetching terminated but no final segment number has been found");
+    }
+    else {
+      m_hasFailure = true;
+    }
+  }
+}
+
+} // namespace ndn::get
diff --git a/tools/get/pipeline-interests-fixed.hpp b/tools/get/pipeline-interests-fixed.hpp
new file mode 100644
index 0000000..6325123
--- /dev/null
+++ b/tools/get/pipeline-interests-fixed.hpp
@@ -0,0 +1,97 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025,  Regents of the University of California,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Wentao Shang
+ * @author Steve DiBenedetto
+ * @author Andrea Tosatto
+ * @author Davide Pesavento
+ * @author Chavoosh Ghasemi
+ */
+
+#ifndef NDN_TOOLS_GET_PIPELINE_INTERESTS_FIXED_HPP
+#define NDN_TOOLS_GET_PIPELINE_INTERESTS_FIXED_HPP
+
+#include "pipeline-interests.hpp"
+
+#include <vector>
+
+namespace ndn::get {
+
+class DataFetcher;
+
+/**
+ * @brief Service for retrieving Data via an Interest pipeline
+ *
+ * Retrieves all segments of Data under a given prefix by maintaining a fixed-size window of
+ * N Interests in flight. A user-specified callback function is used to notify the arrival of
+ * each segment of Data.
+ *
+ * No guarantees are made as to the order in which segments are fetched or callbacks are invoked,
+ * i.e. out-of-order delivery is possible.
+ */
+class PipelineInterestsFixed final : public PipelineInterests
+{
+public:
+  PipelineInterestsFixed(Face& face, const Options& opts);
+
+  ~PipelineInterestsFixed() final;
+
+private:
+  /**
+   * @brief fetch all the segments between 0 and m_lastSegmentNo
+   *
+   * Starts a fixed-window pipeline with size equal to m_options.maxPipelineSize. The pipeline
+   * will fetch every segment until the last segment is successfully received or an error occurs.
+   */
+  void
+  doRun() final;
+
+  void
+  doCancel() final;
+
+  /**
+   * @brief fetch the next segment that has not been requested yet
+   *
+   * @return false if there is an error or all the segments have been fetched, true otherwise
+   */
+  bool
+  fetchNextSegment(size_t pipeNo);
+
+  void
+  handleData(const Interest& interest, const Data& data, size_t pipeNo);
+
+  void
+  handleFail(const std::string& reason, size_t pipeNo);
+
+private:
+  std::vector<std::pair<std::shared_ptr<DataFetcher>, uint64_t>> m_segmentFetchers;
+
+  /**
+   * true if one or more segment fetchers encountered an error; if m_hasFinalBlockId
+   * is false, this is usually not a fatal error for the pipeline
+   */
+  bool m_hasFailure = false;
+};
+
+} // namespace ndn::get
+
+#endif // NDN_TOOLS_GET_PIPELINE_INTERESTS_FIXED_HPP
diff --git a/tools/get/pipeline-interests.cpp b/tools/get/pipeline-interests.cpp
new file mode 100644
index 0000000..afcbd0c
--- /dev/null
+++ b/tools/get/pipeline-interests.cpp
@@ -0,0 +1,160 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Wentao Shang
+ * @author Steve DiBenedetto
+ * @author Andrea Tosatto
+ * @author Davide Pesavento
+ * @author Weiwei Liu
+ * @author Chavoosh Ghasemi
+ */
+
+#include "pipeline-interests.hpp"
+#include "data-fetcher.hpp"
+
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/post.hpp>
+
+#include <iostream>
+
+namespace ndn::get {
+
+PipelineInterests::PipelineInterests(Face& face, const Options& opts)
+  : m_options(opts)
+  , m_face(face)
+{
+}
+
+PipelineInterests::~PipelineInterests() = default;
+
+void
+PipelineInterests::run(const Name& versionedName, DataCallback dataCb, FailureCallback failureCb)
+{
+  BOOST_ASSERT(m_options.disableVersionDiscovery ||
+               (!versionedName.empty() && versionedName[-1].isVersion()));
+  BOOST_ASSERT(dataCb != nullptr);
+
+  m_prefix = versionedName;
+  m_onData = std::move(dataCb);
+  m_onFailure = std::move(failureCb);
+
+  // record the start time of the pipeline
+  m_startTime = time::steady_clock::now();
+
+  doRun();
+}
+
+void
+PipelineInterests::cancel()
+{
+  if (m_isStopping)
+    return;
+
+  m_isStopping = true;
+  doCancel();
+}
+
+bool
+PipelineInterests::allSegmentsReceived() const
+{
+  return m_nReceived > 0 &&
+         m_hasFinalBlockId &&
+         static_cast<uint64_t>(m_nReceived - 1) >= m_lastSegmentNo;
+}
+
+uint64_t
+PipelineInterests::getNextSegmentNo()
+{
+  return m_nextSegmentNo++;
+}
+
+void
+PipelineInterests::onData(const Data& data)
+{
+  m_nReceived++;
+  m_receivedSize += data.getContent().value_size();
+
+  m_onData(data);
+}
+
+void
+PipelineInterests::onFailure(const std::string& reason)
+{
+  if (m_isStopping)
+    return;
+
+  cancel();
+
+  if (m_onFailure) {
+    boost::asio::post(m_face.getIoContext(), [this, reason] { m_onFailure(reason); });
+  }
+}
+
+void
+PipelineInterests::printOptions() const
+{
+  std::cerr << "Pipeline parameters:\n"
+            << "\tRequest fresh content = " << (m_options.mustBeFresh ? "yes" : "no") << "\n"
+            << "\tInterest lifetime = " << m_options.interestLifetime << "\n"
+            << "\tMax retries on timeout or Nack = " <<
+               (m_options.maxRetriesOnTimeoutOrNack == DataFetcher::MAX_RETRIES_INFINITE ?
+                  "infinite" : std::to_string(m_options.maxRetriesOnTimeoutOrNack)) << "\n";
+}
+
+void
+PipelineInterests::printSummary() const
+{
+  using namespace ndn::time;
+  duration<double, seconds::period> timeElapsed = steady_clock::now() - getStartTime();
+  double throughput = 8 * m_receivedSize / timeElapsed.count();
+
+  std::cerr << "\n\nAll segments have been received.\n"
+            << "Time elapsed: " << timeElapsed << "\n"
+            << "Segments received: " << m_nReceived << "\n"
+            << "Transferred size: " << m_receivedSize / 1e3 << " kB" << "\n"
+            << "Goodput: " << formatThroughput(throughput) << "\n";
+}
+
+std::string
+PipelineInterests::formatThroughput(double throughput)
+{
+  int pow = 0;
+  while (throughput >= 1000.0 && pow < 4) {
+    throughput /= 1000.0;
+    pow++;
+  }
+  switch (pow) {
+    case 0:
+      return std::to_string(throughput) + " bit/s";
+    case 1:
+      return std::to_string(throughput) + " kbit/s";
+    case 2:
+      return std::to_string(throughput) + " Mbit/s";
+    case 3:
+      return std::to_string(throughput) + " Gbit/s";
+    case 4:
+      return std::to_string(throughput) + " Tbit/s";
+  }
+  return "";
+}
+
+} // namespace ndn::get
diff --git a/tools/get/pipeline-interests.hpp b/tools/get/pipeline-interests.hpp
new file mode 100644
index 0000000..93245c2
--- /dev/null
+++ b/tools/get/pipeline-interests.hpp
@@ -0,0 +1,186 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2016-2025, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Wentao Shang
+ * @author Steve DiBenedetto
+ * @author Andrea Tosatto
+ * @author Davide Pesavento
+ * @author Weiwei Liu
+ * @author Chavoosh Ghasemi
+ */
+
+#ifndef NDN_TOOLS_GET_PIPELINE_INTERESTS_HPP
+#define NDN_TOOLS_GET_PIPELINE_INTERESTS_HPP
+
+#include "core/common.hpp"
+#include "options.hpp"
+
+#include <ndn-cxx/face.hpp>
+
+#include <functional>
+
+namespace ndn::get {
+
+/**
+ * @brief Service for retrieving Data via an Interest pipeline
+ *
+ * Retrieves all segments of Data under a given prefix by maintaining a (variable or fixed-size)
+ * window of N Interests in flight. A user-specified callback function is used to notify
+ * the arrival of each segment of Data.
+ *
+ * No guarantees are made as to the order in which segments are fetched or callbacks are invoked,
+ * i.e. out-of-order delivery is possible.
+ */
+class PipelineInterests : noncopyable
+{
+public:
+  /**
+   * @brief Constructor.
+   *
+   * Configures the pipelining service without specifying the retrieval namespace.
+   * After construction, the method run() must be called in order to start the pipeline.
+   */
+  PipelineInterests(Face& face, const Options& opts);
+
+  virtual
+  ~PipelineInterests();
+
+  using DataCallback = std::function<void(const Data&)>;
+  using FailureCallback = std::function<void(const std::string& reason)>;
+
+  /**
+   * @brief start fetching all the segments of the specified prefix
+   *
+   * @param versionedName the name of the segmented Data ending with a version number
+   * @param onData callback for every segment correctly received, must not be empty
+   * @param onFailure callback if an error occurs, may be empty
+   */
+  void
+  run(const Name& versionedName, DataCallback onData, FailureCallback onFailure);
+
+  /**
+   * @brief stop all fetch operations
+   */
+  void
+  cancel();
+
+protected:
+  time::steady_clock::time_point
+  getStartTime() const
+  {
+    return m_startTime;
+  }
+
+  bool
+  isStopping() const
+  {
+    return m_isStopping;
+  }
+
+  /**
+   * @brief check if the transfer is complete
+   * @return true if all segments have been received, false otherwise
+   */
+  [[nodiscard]] bool
+  allSegmentsReceived() const;
+
+  /**
+   * @return next segment number to retrieve
+   * @post m_nextSegmentNo == return-value + 1
+   */
+  uint64_t
+  getNextSegmentNo();
+
+  /**
+   * @brief subclasses must call this method to notify successful retrieval of a segment
+   */
+  void
+  onData(const Data& data);
+
+  /**
+   * @brief subclasses can call this method to signal an unrecoverable failure
+   */
+  void
+  onFailure(const std::string& reason);
+
+  void
+  printOptions() const;
+
+  /**
+   * @brief print statistics about this fetching session
+   *
+   * Subclasses can override this method to print additional stats or change the summary format
+   */
+  virtual void
+  printSummary() const;
+
+  /**
+   * @param throughput The throughput in bits/s
+   */
+  static std::string
+  formatThroughput(double throughput);
+
+private:
+  /**
+   * @brief perform subclass-specific operations to fetch all the segments
+   *
+   * When overriding this function, at a minimum, the subclass should implement the retrieving
+   * of all the segments. Subclass must guarantee that `onData` is called once for every
+   * segment that is fetched successfully.
+   *
+   * @note m_lastSegmentNo contains a valid value only if m_hasFinalBlockId is true.
+   */
+  virtual void
+  doRun() = 0;
+
+  virtual void
+  doCancel() = 0;
+
+protected:
+  const Options& m_options;
+  Face& m_face;
+  Name m_prefix;
+
+PUBLIC_WITH_TESTS_ELSE_PROTECTED:
+  bool m_hasFinalBlockId = false; ///< true if the last segment number is known
+  uint64_t m_lastSegmentNo = 0;   ///< valid only if m_hasFinalBlockId == true
+  int64_t m_nReceived = 0;        ///< number of segments received
+  size_t m_receivedSize = 0;      ///< size of received data in bytes
+
+private:
+  DataCallback m_onData;
+  FailureCallback m_onFailure;
+  uint64_t m_nextSegmentNo = 0;
+  time::steady_clock::time_point m_startTime;
+  bool m_isStopping = false;
+};
+
+template<typename Packet>
+uint64_t
+getSegmentFromPacket(const Packet& packet)
+{
+  return packet.getName().at(-1).toSegment();
+}
+
+} // namespace ndn::get
+
+#endif // NDN_TOOLS_GET_PIPELINE_INTERESTS_HPP
diff --git a/tools/get/statistics-collector.cpp b/tools/get/statistics-collector.cpp
new file mode 100644
index 0000000..214402f
--- /dev/null
+++ b/tools/get/statistics-collector.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016-2025,  Regents of the University of California,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Weiwei Liu
+ */
+
+#include "statistics-collector.hpp"
+
+namespace ndn::get {
+
+StatisticsCollector::StatisticsCollector(PipelineInterestsAdaptive& pipeline,
+                                         std::ostream& osCwnd, std::ostream& osRtt)
+  : m_osCwnd(osCwnd)
+  , m_osRtt(osRtt)
+{
+  m_osCwnd << "time\tcwndsize\n";
+  m_osRtt  << "segment\trtt\trttvar\tsrtt\trto\n";
+
+  pipeline.afterCwndChange.connect([this] (time::nanoseconds timeElapsed, double cwnd) {
+    m_osCwnd << timeElapsed.count() / 1e9 << '\t' << cwnd << '\n';
+  });
+
+  pipeline.afterRttMeasurement.connect([this] (const auto& sample) {
+    m_osRtt << sample.segNum << '\t'
+            << sample.rtt.count() / 1e6 << '\t'
+            << sample.rttVar.count() / 1e6 << '\t'
+            << sample.sRtt.count() / 1e6 << '\t'
+            << sample.rto.count() / 1e6 << '\n';
+  });
+}
+
+} // namespace ndn::get
diff --git a/tools/get/statistics-collector.hpp b/tools/get/statistics-collector.hpp
new file mode 100644
index 0000000..4aba545
--- /dev/null
+++ b/tools/get/statistics-collector.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016-2025,  Regents of the University of California,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Weiwei Liu
+ */
+
+#ifndef NDN_TOOLS_GET_STATISTICS_COLLECTOR_HPP
+#define NDN_TOOLS_GET_STATISTICS_COLLECTOR_HPP
+
+#include "pipeline-interests-adaptive.hpp"
+
+namespace ndn::get {
+
+/**
+ * @brief Statistics collector for Adaptive pipelines
+ */
+class StatisticsCollector : noncopyable
+{
+public:
+  StatisticsCollector(PipelineInterestsAdaptive& pipeline,
+                      std::ostream& osCwnd, std::ostream& osRtt);
+
+private:
+  std::ostream& m_osCwnd;
+  std::ostream& m_osRtt;
+};
+
+} // namespace ndn::get
+
+#endif // NDN_TOOLS_GET_STATISTICS_COLLECTOR_HPP
diff --git a/tools/get/wscript b/tools/get/wscript
new file mode 100644
index 0000000..9a325c4
--- /dev/null
+++ b/tools/get/wscript
@@ -0,0 +1,17 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+top = '../..'
+
+def build(bld):
+    bld.objects(
+        target='get-objects',
+        source=bld.path.ant_glob('*.cpp', excl='main.cpp'),
+        use='core-objects')
+
+    bld.program(
+        target=f'{top}/bin/ndnget',
+        name='ndnget',
+        source='main.cpp',
+        use='get-objects')
+
+    # backward compatibility
+    bld.symlink_as('${BINDIR}/ndncatchunks', 'ndnget')
