diff --git a/src/update-handler.cpp b/src/update-handler.cpp
new file mode 100644
index 0000000..3d13b21
--- /dev/null
+++ b/src/update-handler.cpp
@@ -0,0 +1,225 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+* Copyright (c) 2016 Regents of the University of California.
+*
+* This file is part of the nTorrent codebase.
+*
+* nTorrent is free software: you can redistribute it and/or modify it under the
+* terms of the GNU Lesser General Public License as published by the Free Software
+* Foundation, either version 3 of the License, or (at your option) any later version.
+*
+* nTorrent 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 Lesser General Public License for more details.
+*
+* You should have received copies of the GNU General Public License and GNU Lesser
+* General Public License along with nTorrent, e.g., in COPYING.md file. If not, see
+* <http://www.gnu.org/licenses/>.
+*
+* See AUTHORS for complete list of nTorrent authors and contributors.
+*/
+
+#include "update-handler.hpp"
+
+#include <ndn-cxx/security/signing-helpers.hpp>
+
+namespace ndn {
+namespace ntorrent {
+
+void
+UpdateHandler::sendAliveInterest(StatsTable::iterator iter)
+{
+  Name interestName = Name("/NTORRENT" + m_torrentName.toUri() +
+                           "/ALIVE" + m_ownRoutablePrefix.toUri());
+
+  shared_ptr<Interest> i = make_shared<Interest>(interestName);
+
+  // Create and set the LINK object
+  Link link(interestName, { {1, iter->getRecordName()} });
+  m_keyChain->sign(link, signingWithSha256());
+  Block linkWire = link.wireEncode();
+
+  i->setLink(linkWire);
+
+  m_face->expressInterest(*i, bind(&UpdateHandler::decodeDataPacketContent, this, _1, _2),
+                          bind(&UpdateHandler::tryNextRoutablePrefix, this, _1));
+  m_face->processEvents(time::milliseconds(-1));
+}
+
+shared_ptr<Data>
+UpdateHandler::createDataPacket(const Name& name)
+{
+  // Parse the sender's routable prefix contained in the name
+  Name sendersRoutablePrefix = name.getSubName(2 + m_torrentName.size());
+
+  if (m_statsTable->find(sendersRoutablePrefix) == m_statsTable->end()) {
+    m_statsTable->insert(sendersRoutablePrefix);
+  }
+
+  shared_ptr<Data> data = make_shared<Data>(name);
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = encodeContent(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  encodeContent(buffer);
+
+  data->setContentType(tlv::ContentType_Blob);
+  data->setContent(buffer.block());
+
+  return data;
+}
+
+template<encoding::Tag TAG>
+size_t
+UpdateHandler::encodeContent(EncodingImpl<TAG>& encoder) const
+{
+  // Content ::= CONTENT-TYPE TLV-LENGTH
+  //             RoutableName+
+
+  // RoutableName ::= NAME-TYPE TLV-LENGTH
+  //                  Name
+
+  size_t totalLength = 0;
+  // Encode the names of the first five entries of the stats table
+  uint32_t namesEncoded = 0;
+  for (const auto& entry : *m_statsTable) {
+    if (namesEncoded >= MAX_NUM_OF_ENCODED_NAMES) {
+      break;
+    }
+    size_t nameLength = 0;
+    nameLength += entry.getRecordName().wireEncode(encoder);
+    totalLength += nameLength;
+    ++namesEncoded;
+  }
+  totalLength += encoder.prependVarNumber(totalLength);
+  totalLength += encoder.prependVarNumber(tlv::Content);
+  return totalLength;
+}
+
+void
+UpdateHandler::decodeDataPacketContent(const Interest& interest, const Data& data)
+{
+  // Content ::= CONTENT-TYPE TLV-LENGTH
+  //             RoutableName+
+
+  // RoutableName ::= NAME-TYPE TLV-LENGTH
+  //                  Name
+
+  std::cout << "ALIVE data packet received: " << data.getName() << std::endl;
+
+  if (data.getContentType() != tlv::ContentType_Blob) {
+      BOOST_THROW_EXCEPTION(Error("Expected Content Type Blob"));
+  }
+
+  const Block& content = data.getContent();
+  content.parse();
+
+  // Decode the names (maintain their ordering)
+  for (auto element = content.elements_end() - 1; element != content.elements_begin() - 1; element--) {
+    element->parse();
+    Name name(*element);
+    if (name.empty()) {
+      BOOST_THROW_EXCEPTION(Error("Empty routable name was received"));
+    }
+    if (m_statsTable->find(name) == m_statsTable->end()) {
+      m_statsTable->insert(name);
+    }
+  }
+}
+
+bool
+UpdateHandler::needsUpdate()
+{
+  if (m_statsTable->size() < MIN_NUM_OF_ROUTABLE_NAMES) {
+    return true;
+  }
+  for (auto i = m_statsTable->begin(); i != m_statsTable->end(); i++) {
+    if (i->getRecordSuccessRate() >= 0.5) {
+      return false;
+    }
+  }
+  return true;
+}
+
+void
+UpdateHandler::learnOwnRoutablePrefix()
+{
+  Interest i(Name("/localhop/nfd/rib/routable-prefixes"));
+  i.setInterestLifetime(time::milliseconds(100));
+
+  // parse the first contained routable prefix and set it as the ownRoutablePrefix
+  auto prefixReceived = [this] (const Interest& interest, const Data& data) {
+    const Block& content = data.getContent();
+    content.parse();
+
+    auto element = content.elements_begin();
+    element->parse();
+    Name ownRoutablePrefix(*element);
+    m_ownRoutablePrefix = ownRoutablePrefix;
+  };
+
+  auto prefixRetrievalFailed = [this] (const Interest&) {
+    std::cerr << "Own Routable Prefix Retrieval Failed. Trying again." << std::endl;
+    // TODO(Spyros): This could lead to an infinite loop. Figure out something better...
+    this->learnOwnRoutablePrefix();
+  };
+
+  m_face->expressInterest(i, prefixReceived, prefixRetrievalFailed);
+  m_face->processEvents(time::milliseconds(-1));
+}
+
+void
+UpdateHandler::onInterestReceived(const InterestFilter& filter, const Interest& interest)
+{
+  std::cout << "Interest Received: " << interest.getName().toUri() << std::endl;
+  shared_ptr<Data> data = this->createDataPacket(interest.getName());
+  m_keyChain->sign(*data, signingWithSha256());
+  m_face->put(*data);
+}
+
+void
+UpdateHandler::onRegisterFailed(const Name& prefix, const std::string& reason)
+{
+  std::cerr << "ERROR: Failed to register prefix \""
+            << prefix << "\" in local hub's daemon (" << reason << ")"
+            << std::endl;
+  m_face->shutdown();
+}
+
+void
+UpdateHandler::tryNextRoutablePrefix(const Interest& interest)
+{
+  Link link(interest.getLink());
+  const Name& name = link.getDelegations().begin()->second;
+  auto iter = m_statsTable->find(name);
+
+  if (iter != m_statsTable->end()) {
+    if (iter + 1 == m_statsTable->end()) {
+      iter = m_statsTable->begin();
+    }
+    else {
+      ++iter;
+    }
+  }
+  else {
+    iter = m_statsTable->begin();
+  }
+
+  shared_ptr<Interest> newInterest = make_shared<Interest>(interest);
+
+  link.removeDelegation(name);
+  link.addDelegation(1, iter->getRecordName());
+
+  m_keyChain->sign(link, signingWithSha256());
+  Block block = link.wireEncode();
+
+  newInterest->setLink(block);
+
+  m_face->expressInterest(*newInterest, bind(&UpdateHandler::decodeDataPacketContent, this, _1, _2),
+                          bind(&UpdateHandler::tryNextRoutablePrefix, this, _1));
+  m_face->processEvents(time::milliseconds(-1));
+}
+
+} // namespace ntorrent
+} // namespace ndn
