Improve and simplify code with modern C++ features

Change-Id: I83bf5513c2a1f90ba5a59e93c473306864b27d94
diff --git a/daemon/face/channel.hpp b/daemon/face/channel.hpp
index 5b870fe..db97cc8 100644
--- a/daemon/face/channel.hpp
+++ b/daemon/face/channel.hpp
@@ -84,25 +84,14 @@
  *  Parameters are passed as a struct rather than individually, so that a future change in the list
  *  of parameters does not require an update to the method signature in all subclasses.
  */
-class FaceParams
+struct FaceParams
 {
-public:
-  // get rid of this constructor and use aggregate init + NSDMIs when we switch to C++14
-  FaceParams() noexcept
-    : persistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
-    , wantLocalFields(false)
-    , wantLpReliability(false)
-    , wantCongestionMarking(boost::logic::indeterminate)
-  {
-  }
-
-public:
-  ndn::nfd::FacePersistency persistency;
+  ndn::nfd::FacePersistency persistency = ndn::nfd::FACE_PERSISTENCY_PERSISTENT;
   optional<time::nanoseconds> baseCongestionMarkingInterval;
   optional<uint64_t> defaultCongestionThreshold;
-  bool wantLocalFields;
-  bool wantLpReliability;
-  boost::logic::tribool wantCongestionMarking;
+  bool wantLocalFields = false;
+  bool wantLpReliability = false;
+  boost::logic::tribool wantCongestionMarking = boost::logic::indeterminate;
 };
 
 /** \brief invokes a callback when the face is closed
diff --git a/daemon/face/datagram-transport.hpp b/daemon/face/datagram-transport.hpp
index 0b375ad..669b46e 100644
--- a/daemon/face/datagram-transport.hpp
+++ b/daemon/face/datagram-transport.hpp
@@ -72,12 +72,10 @@
   doSend(Transport::Packet&& packet) override;
 
   void
-  handleSend(const boost::system::error_code& error,
-             size_t nBytesSent, const Block& payload);
+  handleSend(const boost::system::error_code& error, size_t nBytesSent);
 
   void
-  handleReceive(const boost::system::error_code& error,
-                size_t nBytesReceived);
+  handleReceive(const boost::system::error_code& error, size_t nBytesReceived);
 
   void
   processErrorCode(const boost::system::error_code& error);
@@ -120,9 +118,9 @@
   }
 
   m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
-                              bind(&DatagramTransport<T, U>::handleReceive, this,
-                                   boost::asio::placeholders::error,
-                                   boost::asio::placeholders::bytes_transferred));
+                              [this] (auto&&... args) {
+                                this->handleReceive(std::forward<decltype(args)>(args)...);
+                              });
 }
 
 template<class T, class U>
@@ -164,10 +162,10 @@
   NFD_LOG_FACE_TRACE(__func__);
 
   m_socket.async_send(boost::asio::buffer(packet.packet),
-                      bind(&DatagramTransport<T, U>::handleSend, this,
-                           boost::asio::placeholders::error,
-                           boost::asio::placeholders::bytes_transferred,
-                           packet.packet));
+                      // packet.packet is copied into the lambda to retain the underlying Buffer
+                      [this, p = packet.packet] (auto&&... args) {
+                        this->handleSend(std::forward<decltype(args)>(args)...);
+                      });
 }
 
 template<class T, class U>
@@ -202,23 +200,20 @@
 
 template<class T, class U>
 void
-DatagramTransport<T, U>::handleReceive(const boost::system::error_code& error,
-                                       size_t nBytesReceived)
+DatagramTransport<T, U>::handleReceive(const boost::system::error_code& error, size_t nBytesReceived)
 {
   receiveDatagram(m_receiveBuffer.data(), nBytesReceived, error);
 
   if (m_socket.is_open())
     m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
-                                bind(&DatagramTransport<T, U>::handleReceive, this,
-                                     boost::asio::placeholders::error,
-                                     boost::asio::placeholders::bytes_transferred));
+                                [this] (auto&&... args) {
+                                  this->handleReceive(std::forward<decltype(args)>(args)...);
+                                });
 }
 
 template<class T, class U>
 void
-DatagramTransport<T, U>::handleSend(const boost::system::error_code& error,
-                                    size_t nBytesSent, const Block& payload)
-// 'payload' is unused; it's needed to retain the underlying Buffer
+DatagramTransport<T, U>::handleSend(const boost::system::error_code& error, size_t nBytesSent)
 {
   if (error)
     return processErrorCode(error);
@@ -266,7 +261,7 @@
 
 template<class T, class U>
 Transport::EndpointId
-DatagramTransport<T, U>::makeEndpointId(const typename protocol::endpoint& ep)
+DatagramTransport<T, U>::makeEndpointId(const typename protocol::endpoint&)
 {
   return 0;
 }
diff --git a/daemon/face/ethernet-channel.cpp b/daemon/face/ethernet-channel.cpp
index 3791d44..69c6f45 100644
--- a/daemon/face/ethernet-channel.cpp
+++ b/daemon/face/ethernet-channel.cpp
@@ -65,7 +65,7 @@
   catch (const boost::system::system_error& e) {
     NFD_LOG_CHAN_DEBUG("Face creation for " << remoteEndpoint << " failed: " << e.what());
     if (onConnectFailed)
-      onConnectFailed(504, std::string("Face creation failed: ") + e.what());
+      onConnectFailed(504, "Face creation failed: "s + e.what());
     return;
   }
 
@@ -102,9 +102,7 @@
                            const FaceCreationFailedCallback& onReceiveFailed)
 {
   m_socket.async_read_some(boost::asio::null_buffers(),
-                           bind(&EthernetChannel::handleRead, this,
-                                boost::asio::placeholders::error,
-                                onFaceCreated, onReceiveFailed));
+                           [=] (const auto& e, auto) { this->handleRead(e, onFaceCreated, onReceiveFailed); });
 }
 
 void
@@ -172,7 +170,7 @@
   catch (const EthernetTransport::Error& e) {
     NFD_LOG_CHAN_DEBUG("Face creation for " << sender << " failed: " << e.what());
     if (onReceiveFailed)
-      onReceiveFailed(504, std::string("Face creation failed: ") + e.what());
+      onReceiveFailed(504, "Face creation failed: "s + e.what());
     return;
   }
 
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index d921855..f9767df 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -46,11 +46,10 @@
 EthernetFactory::EthernetFactory(const CtorParams& params)
   : ProtocolFactory(params)
 {
-  m_netifAddConn = netmon->onInterfaceAdded.connect(
-    [this] (const shared_ptr<const ndn::net::NetworkInterface>& netif) {
-      this->applyUnicastConfigToNetif(netif);
-      this->applyMcastConfigToNetif(*netif);
-    });
+  m_netifAddConn = netmon->onInterfaceAdded.connect([this] (const auto& netif) {
+    this->applyUnicastConfigToNetif(netif);
+    this->applyMcastConfigToNetif(*netif);
+  });
 }
 
 void
diff --git a/daemon/face/ethernet-transport.cpp b/daemon/face/ethernet-transport.cpp
index a7e8907..e2ba043 100644
--- a/daemon/face/ethernet-transport.cpp
+++ b/daemon/face/ethernet-transport.cpp
@@ -122,8 +122,7 @@
 EthernetTransport::asyncRead()
 {
   m_socket.async_read_some(boost::asio::null_buffers(),
-                           bind(&EthernetTransport::handleRead, this,
-                                boost::asio::placeholders::error));
+                           [this] (const auto& e, auto) { this->handleRead(e); });
 }
 
 void
diff --git a/daemon/face/face-system.cpp b/daemon/face/face-system.cpp
index 1d2db37..872efef 100644
--- a/daemon/face/face-system.cpp
+++ b/daemon/face/face-system.cpp
@@ -47,7 +47,7 @@
 ProtocolFactoryCtorParams
 FaceSystem::makePFCtorParams()
 {
-  auto addFace = bind(&FaceTable::add, &m_faceTable, _1);
+  auto addFace = [&ft = m_faceTable] (auto face) { ft.add(std::move(face)); };
   return {addFace, m_netmon};
 }
 
diff --git a/daemon/face/generic-link-service.cpp b/daemon/face/generic-link-service.cpp
index 5122755..e2f7e0e 100644
--- a/daemon/face/generic-link-service.cpp
+++ b/daemon/face/generic-link-service.cpp
@@ -36,17 +36,6 @@
 
 constexpr uint32_t DEFAULT_CONGESTION_THRESHOLD_DIVISOR = 2;
 
-GenericLinkService::Options::Options()
-  : allowLocalFields(false)
-  , allowFragmentation(false)
-  , allowReassembly(false)
-  , allowCongestionMarking(false)
-  , baseCongestionMarkingInterval(time::milliseconds(100)) // Interval from RFC 8289 (CoDel)
-  , defaultCongestionThreshold(65536) // This default value works well for a queue capacity of 200KiB
-  , allowSelfLearning(false)
-{
-}
-
 GenericLinkService::GenericLinkService(const GenericLinkService::Options& options)
   : m_options(options)
   , m_fragmenter(m_options.fragmenterOptions, this)
@@ -57,8 +46,8 @@
   , m_lastMarkTime(time::steady_clock::TimePoint::min())
   , m_nMarkedSinceInMarkingState(0)
 {
-  m_reassembler.beforeTimeout.connect(bind([this] { ++this->nReassemblyTimeouts; }));
-  m_reliability.onDroppedInterest.connect([this] (const Interest& i) { this->notifyDroppedInterest(i); });
+  m_reassembler.beforeTimeout.connect([this] (auto...) { ++this->nReassemblyTimeouts; });
+  m_reliability.onDroppedInterest.connect([this] (const auto& i) { this->notifyDroppedInterest(i); });
   nReassembling.observe(&m_reassembler);
 }
 
@@ -226,7 +215,7 @@
 void
 GenericLinkService::assignSequences(std::vector<lp::Packet>& pkts)
 {
-  std::for_each(pkts.begin(), pkts.end(), bind(&GenericLinkService::assignSequence, this, _1));
+  std::for_each(pkts.begin(), pkts.end(), [this] (auto& pkt) { this->assignSequence(pkt); });
 }
 
 void
diff --git a/daemon/face/generic-link-service.hpp b/daemon/face/generic-link-service.hpp
index d0eb3dd..c8eea37 100644
--- a/daemon/face/generic-link-service.hpp
+++ b/daemon/face/generic-link-service.hpp
@@ -98,16 +98,19 @@
   class Options
   {
   public:
-    Options();
+    constexpr
+    Options() noexcept
+    {
+    }
 
   public:
     /** \brief enables encoding of IncomingFaceId, and decoding of NextHopFaceId and CachePolicy
      */
-    bool allowLocalFields;
+    bool allowLocalFields = false;
 
     /** \brief enables fragmentation
      */
-    bool allowFragmentation;
+    bool allowFragmentation = false;
 
     /** \brief options for fragmentation
      */
@@ -115,7 +118,7 @@
 
     /** \brief enables reassembly
      */
-    bool allowReassembly;
+    bool allowReassembly = false;
 
     /** \brief options for reassembly
      */
@@ -127,19 +130,23 @@
 
     /** \brief enables send queue congestion detection and marking
      */
-    bool allowCongestionMarking;
+    bool allowCongestionMarking = false;
 
     /** \brief starting value for congestion marking interval
+     *
+     *  The default value (100 ms) is taken from RFC 8289 (CoDel).
      */
-    time::nanoseconds baseCongestionMarkingInterval;
+    time::nanoseconds baseCongestionMarkingInterval = 100_ms;
 
     /** \brief default congestion threshold in bytes
+     *
+     *  The default value (64 KiB) works well for a queue capacity of 200 KiB.
      */
-    size_t defaultCongestionThreshold;
+    size_t defaultCongestionThreshold = 65536;
 
     /** \brief enables self-learning forwarding support
      */
-    bool allowSelfLearning;
+    bool allowSelfLearning = false;
   };
 
   /** \brief counters provided by GenericLinkService
@@ -147,7 +154,7 @@
   using Counters = GenericLinkServiceCounters;
 
   explicit
-  GenericLinkService(const Options& options = Options());
+  GenericLinkService(const Options& options = {});
 
   /** \brief get Options used by GenericLinkService
    */
@@ -283,6 +290,7 @@
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   /// CongestionMark TLV-TYPE (3 octets) + CongestionMark TLV-LENGTH (1 octet) + sizeof(uint64_t)
   static constexpr size_t CONGESTION_MARK_SIZE = 3 + 1 + sizeof(uint64_t);
+
   /// Time to mark next packet due to send queue congestion
   time::steady_clock::TimePoint m_nextMarkTime;
   /// Time last packet was marked
diff --git a/daemon/face/lp-fragmenter.cpp b/daemon/face/lp-fragmenter.cpp
index 1928bf5..7494ca7 100644
--- a/daemon/face/lp-fragmenter.cpp
+++ b/daemon/face/lp-fragmenter.cpp
@@ -57,11 +57,6 @@
   1 + 1 + 8 + // FragCount TLV
   1 + 9; // Fragment TLV-TYPE and TLV-LENGTH
 
-LpFragmenter::Options::Options()
-  : nMaxFragments(400)
-{
-}
-
 LpFragmenter::LpFragmenter(const LpFragmenter::Options& options, const LinkService* linkService)
   : m_options(options)
   , m_linkService(linkService)
@@ -122,7 +117,7 @@
   // compute FragCount
   if (fragCount > m_options.nMaxFragments) {
     NFD_LOG_FACE_WARN("fragmentation error, FragCount over limit: DROP");
-    return std::make_pair(false, std::vector<lp::Packet>{});
+    return std::make_tuple(false, std::vector<lp::Packet>{});
   }
 
   // populate fragments
@@ -135,7 +130,7 @@
     lp::Packet& frag = frags[fragIndex];
     frag.add<lp::FragIndexField>(fragIndex);
     frag.add<lp::FragCountField>(fragCount);
-    frag.set<lp::FragmentField>(std::make_pair(fragBegin, fragEnd));
+    frag.set<lp::FragmentField>({fragBegin, fragEnd});
     BOOST_ASSERT(frag.wireEncode().size() <= mtu);
 
     ++fragIndex;
@@ -144,7 +139,7 @@
   }
   BOOST_ASSERT(fragIndex == fragCount);
 
-  return std::make_pair(true, frags);
+  return std::make_tuple(true, frags);
 }
 
 std::ostream&
diff --git a/daemon/face/lp-fragmenter.hpp b/daemon/face/lp-fragmenter.hpp
index 40d32cb..51d14d9 100644
--- a/daemon/face/lp-fragmenter.hpp
+++ b/daemon/face/lp-fragmenter.hpp
@@ -44,19 +44,15 @@
 public:
   /** \brief Options that control the behavior of LpFragmenter
    */
-  class Options
+  struct Options
   {
-  public:
-    Options();
-
-  public:
     /** \brief maximum number of fragments in a packet
      */
-    size_t nMaxFragments;
+    size_t nMaxFragments = 400;
   };
 
   explicit
-  LpFragmenter(const Options& options = Options(), const LinkService* linkService = nullptr);
+  LpFragmenter(const Options& options, const LinkService* linkService = nullptr);
 
   /** \brief set options for fragmenter
    */
diff --git a/daemon/face/lp-reassembler.cpp b/daemon/face/lp-reassembler.cpp
index a6d1c60..cd6f873 100644
--- a/daemon/face/lp-reassembler.cpp
+++ b/daemon/face/lp-reassembler.cpp
@@ -33,12 +33,6 @@
 
 NFD_LOG_INIT(LpReassembler);
 
-LpReassembler::Options::Options()
-  : nMaxFragments(400)
-  , reassemblyTimeout(time::milliseconds(500))
-{
-}
-
 LpReassembler::LpReassembler(const LpReassembler::Options& options, const LinkService* linkService)
   : m_options(options)
   , m_linkService(linkService)
@@ -119,8 +113,7 @@
   }
 
   // set drop timer
-  pp.dropTimer = scheduler::schedule(m_options.reassemblyTimeout,
-                                     bind(&LpReassembler::timeoutPartialPacket, this, key));
+  pp.dropTimer = scheduler::schedule(m_options.reassemblyTimeout, [=] { timeoutPartialPacket(key); });
 
   return FALSE_RETURN;
 }
@@ -130,7 +123,7 @@
 {
   PartialPacket& pp = m_partialPackets[key];
 
-  size_t payloadSize = std::accumulate(pp.fragments.begin(), pp.fragments.end(), 0,
+  size_t payloadSize = std::accumulate(pp.fragments.begin(), pp.fragments.end(), 0U,
     [&] (size_t sum, const lp::Packet& pkt) -> size_t {
       ndn::Buffer::const_iterator fragBegin, fragEnd;
       std::tie(fragBegin, fragEnd) = pkt.get<lp::FragmentField>();
@@ -138,7 +131,7 @@
     });
 
   ndn::Buffer fragBuffer(payloadSize);
-  ndn::Buffer::iterator it = fragBuffer.begin();
+  auto it = fragBuffer.begin();
 
   for (const lp::Packet& frag : pp.fragments) {
     ndn::Buffer::const_iterator fragBegin, fragEnd;
diff --git a/daemon/face/lp-reassembler.hpp b/daemon/face/lp-reassembler.hpp
index fd0d874..f416b2c 100644
--- a/daemon/face/lp-reassembler.hpp
+++ b/daemon/face/lp-reassembler.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -38,32 +38,28 @@
 class LinkService;
 
 /** \brief reassembles fragmented network-layer packets
- *  \sa http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
+ *  \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
  */
 class LpReassembler : noncopyable
 {
 public:
   /** \brief Options that control the behavior of LpReassembler
    */
-  class Options
+  struct Options
   {
-  public:
-    Options();
-
-  public:
     /** \brief maximum number of fragments in a packet
      *
      *  LpPackets with FragCount over this limit are dropped.
      */
-    size_t nMaxFragments;
+    size_t nMaxFragments = 400;
 
     /** \brief timeout before a partially reassembled packet is dropped
      */
-    time::nanoseconds reassemblyTimeout;
+    time::nanoseconds reassemblyTimeout = 500_ms;
   };
 
   explicit
-  LpReassembler(const Options& options = Options(), const LinkService* linkService = nullptr);
+  LpReassembler(const Options& options, const LinkService* linkService = nullptr);
 
   /** \brief set options for reassembler
    */
diff --git a/daemon/face/lp-reliability.cpp b/daemon/face/lp-reliability.cpp
index 5a4621d..7b248fb 100644
--- a/daemon/face/lp-reliability.cpp
+++ b/daemon/face/lp-reliability.cpp
@@ -39,13 +39,13 @@
 {
   BOOST_ASSERT(m_linkService != nullptr);
 
-  BOOST_ASSERT(m_options.idleAckTimerPeriod > time::nanoseconds::zero());
+  BOOST_ASSERT(m_options.idleAckTimerPeriod > 0_ns);
 }
 
 void
 LpReliability::setOptions(const Options& options)
 {
-  BOOST_ASSERT(options.idleAckTimerPeriod > time::nanoseconds::zero());
+  BOOST_ASSERT(options.idleAckTimerPeriod > 0_ns);
 
   if (m_options.isEnabled && !options.isEnabled) {
     this->stopIdleAckTimer();
@@ -81,8 +81,7 @@
                                                  std::forward_as_tuple(txSeq),
                                                  std::forward_as_tuple(frag));
     unackedFragsIt->second.sendTime = sendTime;
-    unackedFragsIt->second.rtoTimer =
-      scheduler::schedule(m_rto.computeRto(), bind(&LpReliability::onLpPacketLost, this, txSeq));
+    unackedFragsIt->second.rtoTimer = scheduler::schedule(m_rto.computeRto(), [=] { onLpPacketLost(txSeq); });
     unackedFragsIt->second.netPkt = netPkt;
 
     if (m_unackedFrags.size() == 1) {
@@ -305,8 +304,7 @@
     m_linkService->sendLpPacket(lp::Packet(newTxFrag.pkt));
 
     // Start RTO timer for this sequence
-    newTxFrag.rtoTimer = scheduler::schedule(m_rto.computeRto(),
-                                          bind(&LpReliability::onLpPacketLost, this, newTxSeq));
+    newTxFrag.rtoTimer = scheduler::schedule(m_rto.computeRto(), [=] { onLpPacketLost(newTxSeq); });
   }
 
   return removedThisTxSeq;
diff --git a/daemon/face/lp-reliability.hpp b/daemon/face/lp-reliability.hpp
index 896cc0e..9521183 100644
--- a/daemon/face/lp-reliability.hpp
+++ b/daemon/face/lp-reliability.hpp
@@ -57,7 +57,7 @@
 
     /** \brief period between sending pending Acks in an IDLE packet
      */
-    time::nanoseconds idleAckTimerPeriod = time::milliseconds(5);
+    time::nanoseconds idleAckTimerPeriod = 5_ms;
 
     /** \brief a fragment is considered lost if this number of fragments with greater sequence
      *         numbers are acknowledged
diff --git a/daemon/face/multicast-udp-transport.cpp b/daemon/face/multicast-udp-transport.cpp
index 3574158..a01063b 100644
--- a/daemon/face/multicast-udp-transport.cpp
+++ b/daemon/face/multicast-udp-transport.cpp
@@ -87,10 +87,10 @@
   NFD_LOG_FACE_TRACE(__func__);
 
   m_sendSocket.async_send_to(boost::asio::buffer(packet.packet), m_multicastGroup,
-                             bind(&MulticastUdpTransport::handleSend, this,
-                                  boost::asio::placeholders::error,
-                                  boost::asio::placeholders::bytes_transferred,
-                                  packet.packet));
+                             // packet.packet is copied into the lambda to retain the underlying Buffer
+                             [this, p = packet.packet] (auto&&... args) {
+                               this->handleSend(std::forward<decltype(args)>(args)...);
+                             });
 }
 
 void
diff --git a/daemon/face/stream-transport.hpp b/daemon/face/stream-transport.hpp
index d70e4f6..9daf29e 100644
--- a/daemon/face/stream-transport.hpp
+++ b/daemon/face/stream-transport.hpp
@@ -200,9 +200,7 @@
 StreamTransport<T>::sendFromQueue()
 {
   boost::asio::async_write(m_socket, boost::asio::buffer(m_sendQueue.front()),
-                           bind(&StreamTransport<T>::handleSend, this,
-                                boost::asio::placeholders::error,
-                                boost::asio::placeholders::bytes_transferred));
+                           [this] (auto&&... args) { this->handleSend(std::forward<decltype(args)>(args)...); });
 }
 
 template<class T>
@@ -232,9 +230,7 @@
 
   m_socket.async_receive(boost::asio::buffer(m_receiveBuffer + m_receiveBufferSize,
                                              ndn::MAX_NDN_PACKET_SIZE - m_receiveBufferSize),
-                         bind(&StreamTransport<T>::handleReceive, this,
-                              boost::asio::placeholders::error,
-                              boost::asio::placeholders::bytes_transferred));
+                         [this] (auto&&... args) { this->handleReceive(std::forward<decltype(args)>(args)...); });
 }
 
 template<class T>
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
index 1e6b410..639b27d 100644
--- a/daemon/face/tcp-channel.cpp
+++ b/daemon/face/tcp-channel.cpp
@@ -83,15 +83,15 @@
     return;
   }
 
-  auto clientSocket = make_shared<ip::tcp::socket>(ref(getGlobalIoService()));
-  auto timeoutEvent = scheduler::schedule(timeout, bind(&TcpChannel::handleConnectTimeout, this,
-                                                        remoteEndpoint, clientSocket, onConnectFailed));
+  auto clientSocket = make_shared<ip::tcp::socket>(std::ref(getGlobalIoService()));
+  auto timeoutEvent = scheduler::schedule(timeout, [=] {
+    handleConnectTimeout(remoteEndpoint, clientSocket, onConnectFailed);
+  });
 
   NFD_LOG_CHAN_TRACE("Connecting to " << remoteEndpoint);
-  clientSocket->async_connect(remoteEndpoint,
-                              bind(&TcpChannel::handleConnect, this,
-                                   boost::asio::placeholders::error, remoteEndpoint, clientSocket,
-                                   params, timeoutEvent, onFaceCreated, onConnectFailed));
+  clientSocket->async_connect(remoteEndpoint, [=] (const auto& e) {
+    this->handleConnect(e, remoteEndpoint, clientSocket, params, timeoutEvent, onFaceCreated, onConnectFailed);
+  });
 }
 
 void
@@ -151,9 +151,7 @@
 TcpChannel::accept(const FaceCreatedCallback& onFaceCreated,
                    const FaceCreationFailedCallback& onAcceptFailed)
 {
-  m_acceptor.async_accept(m_socket, bind(&TcpChannel::handleAccept, this,
-                                         boost::asio::placeholders::error,
-                                         onFaceCreated, onAcceptFailed));
+  m_acceptor.async_accept(m_socket, [=] (const auto& e) { this->handleAccept(e, onFaceCreated, onAcceptFailed); });
 }
 
 void
diff --git a/daemon/face/tcp-transport.cpp b/daemon/face/tcp-transport.cpp
index ad1be5d..78d7097 100644
--- a/daemon/face/tcp-transport.cpp
+++ b/daemon/face/tcp-transport.cpp
@@ -35,8 +35,8 @@
 
 NFD_LOG_MEMBER_INIT_SPECIALIZED(StreamTransport<boost::asio::ip::tcp>, TcpTransport);
 
-time::milliseconds TcpTransport::s_initialReconnectWait = time::seconds(1);
-time::milliseconds TcpTransport::s_maxReconnectWait = time::minutes(5);
+time::milliseconds TcpTransport::s_initialReconnectWait = 1_s;
+time::milliseconds TcpTransport::s_maxReconnectWait = 5_min;
 float TcpTransport::s_reconnectWaitMultiplier = 2.0f;
 
 TcpTransport::TcpTransport(protocol::socket&& socket, ndn::nfd::FacePersistency persistency, ndn::nfd::FaceScope faceScope)
@@ -134,10 +134,8 @@
   this->resetReceiveBuffer();
   this->resetSendQueue();
 
-  m_reconnectEvent = scheduler::schedule(m_nextReconnectWait,
-                                         [this] { handleReconnectTimeout(); });
-  m_socket.async_connect(m_remoteEndpoint,
-                         [this] (const boost::system::error_code& error) { handleReconnect(error); });
+  m_reconnectEvent = scheduler::schedule(m_nextReconnectWait, [this] { this->handleReconnectTimeout(); });
+  m_socket.async_connect(m_remoteEndpoint, [this] (const auto& e) { this->handleReconnect(e); });
 }
 
 void
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index 3d6e6b8..b87e697 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -60,7 +60,7 @@
   catch (const boost::system::system_error& e) {
     NFD_LOG_CHAN_DEBUG("Face creation for " << remoteEndpoint << " failed: " << e.what());
     if (onConnectFailed)
-      onConnectFailed(504, std::string("Face creation failed: ") + e.what());
+      onConnectFailed(504, "Face creation failed: "s + e.what());
     return;
   }
 
@@ -94,10 +94,9 @@
                            const FaceCreationFailedCallback& onReceiveFailed)
 {
   m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_remoteEndpoint,
-                              bind(&UdpChannel::handleNewPeer, this,
-                                   boost::asio::placeholders::error,
-                                   boost::asio::placeholders::bytes_transferred,
-                                   onFaceCreated, onReceiveFailed));
+                              [=] (auto&&... args) {
+                                this->handleNewPeer(std::forward<decltype(args)>(args)..., onFaceCreated, onReceiveFailed);
+                              });
 }
 
 void
@@ -127,7 +126,7 @@
   catch (const boost::system::system_error& e) {
     NFD_LOG_CHAN_DEBUG("Face creation for " << m_remoteEndpoint << " failed: " << e.what());
     if (onReceiveFailed)
-      onReceiveFailed(504, std::string("Face creation failed: ") + e.what());
+      onReceiveFailed(504, "Face creation failed: "s + e.what());
     return;
   }
 
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 5d28bed..3660db5 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -50,7 +50,9 @@
 UdpFactory::UdpFactory(const CtorParams& params)
   : ProtocolFactory(params)
 {
-  m_netifAddConn = netmon->onInterfaceAdded.connect(bind(&UdpFactory::applyMcastConfigToNetif, this, _1));
+  m_netifAddConn = netmon->onInterfaceAdded.connect([this] (const auto& netif) {
+    this->applyMcastConfigToNetif(netif);
+  });
 }
 
 void
@@ -414,7 +416,7 @@
     NFD_LOG_DEBUG("Not creating multicast faces on " << netif->getName() << ": no viable IP address");
     // keep an eye on new addresses
     m_netifConns[netif->getIndex()].addrAddConn =
-      netif->onAddressAdded.connect(bind(&UdpFactory::applyMcastConfigToNetif, this, netif));
+      netif->onAddressAdded.connect([=] (auto...) { this->applyMcastConfigToNetif(netif); });
     return {};
   }
 
diff --git a/daemon/face/unix-stream-channel.cpp b/daemon/face/unix-stream-channel.cpp
index a127c84..8c58c55 100644
--- a/daemon/face/unix-stream-channel.cpp
+++ b/daemon/face/unix-stream-channel.cpp
@@ -101,7 +101,7 @@
   m_acceptor.bind(m_endpoint);
   m_acceptor.listen(backlog);
 
-  if (::chmod(m_endpoint.path().c_str(), 0666) < 0) {
+  if (::chmod(m_endpoint.path().data(), 0666) < 0) {
     BOOST_THROW_EXCEPTION(Error("chmod(" + m_endpoint.path() + ") failed: " + std::strerror(errno)));
   }
 
@@ -113,9 +113,7 @@
 UnixStreamChannel::accept(const FaceCreatedCallback& onFaceCreated,
                           const FaceCreationFailedCallback& onAcceptFailed)
 {
-  m_acceptor.async_accept(m_socket, bind(&UnixStreamChannel::handleAccept, this,
-                                         boost::asio::placeholders::error,
-                                         onFaceCreated, onAcceptFailed));
+  m_acceptor.async_accept(m_socket, [=] (const auto& e) { this->handleAccept(e, onFaceCreated, onAcceptFailed); });
 }
 
 void
diff --git a/daemon/face/websocket-channel.cpp b/daemon/face/websocket-channel.cpp
index 2ac9384..ca149b3 100644
--- a/daemon/face/websocket-channel.cpp
+++ b/daemon/face/websocket-channel.cpp
@@ -117,7 +117,7 @@
   NFD_LOG_CHAN_TRACE("Incoming connection from " << m_server.get_con_from_hdl(hdl)->get_remote_endpoint());
 
   auto linkService = make_unique<GenericLinkService>();
-  auto transport = make_unique<WebSocketTransport>(hdl, ref(m_server), m_pingInterval);
+  auto transport = make_unique<WebSocketTransport>(hdl, std::ref(m_server), m_pingInterval);
   auto face = make_shared<Face>(std::move(linkService), std::move(transport));
 
   BOOST_ASSERT(m_channelFaces.count(hdl) == 0);
diff --git a/daemon/face/websocket-transport.cpp b/daemon/face/websocket-transport.cpp
index 97af039..4262287 100644
--- a/daemon/face/websocket-transport.cpp
+++ b/daemon/face/websocket-transport.cpp
@@ -97,7 +97,7 @@
 
   bool isOk = false;
   Block element;
-  std::tie(isOk, element) = Block::fromBuffer(reinterpret_cast<const uint8_t*>(msg.c_str()), msg.size());
+  std::tie(isOk, element) = Block::fromBuffer(reinterpret_cast<const uint8_t*>(msg.data()), msg.size());
   if (!isOk) {
     NFD_LOG_FACE_WARN("Failed to parse message payload");
     return;
@@ -109,7 +109,7 @@
 void
 WebSocketTransport::schedulePing()
 {
-  m_pingEventId = scheduler::schedule(m_pingInterval, bind(&WebSocketTransport::sendPing, this));
+  m_pingEventId = scheduler::schedule(m_pingInterval, [this] { sendPing(); });
 }
 
 void