face: allow setting default UDP face MTU in config

refs #5138

Change-Id: Ibb3767b27aec2b046d1f41292f3d61001866f8c0
diff --git a/daemon/face/channel.cpp b/daemon/face/channel.cpp
index 8b1333e..dd3b118 100644
--- a/daemon/face/channel.cpp
+++ b/daemon/face/channel.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019,  Regents of the University of California,
+ * Copyright (c) 2014-2021,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -38,6 +38,12 @@
 }
 
 void
+Channel::setDefaultMtu(size_t mtu)
+{
+  m_defaultMtu = mtu;
+}
+
+void
 connectFaceClosedSignal(Face& face, std::function<void()> f)
 {
   face.afterStateChange.connect([f = std::move(f)] (auto, FaceState newState) {
diff --git a/daemon/face/channel.hpp b/daemon/face/channel.hpp
index ffd06d7..f486feb 100644
--- a/daemon/face/channel.hpp
+++ b/daemon/face/channel.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2020,  Regents of the University of California,
+ * Copyright (c) 2014-2021,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -50,6 +50,14 @@
     return m_uri;
   }
 
+  /** \brief Returns the default MTU for all faces created by this channel
+   */
+  size_t
+  getDefaultMtu() const
+  {
+    return m_defaultMtu;
+  }
+
   /** \brief Returns whether the channel is listening
    */
   virtual bool
@@ -64,8 +72,12 @@
   void
   setUri(const FaceUri& uri);
 
+  void
+  setDefaultMtu(size_t mtu);
+
 private:
   FaceUri m_uri;
+  size_t m_defaultMtu = ndn::MAX_NDN_PACKET_SIZE;
 };
 
 /** \brief Prototype for the callback that is invoked when a face is created
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index f2ccb9c..a5d9dee 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2020,  Regents of the University of California,
+ * Copyright (c) 2014-2021,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -38,13 +38,15 @@
 
 UdpChannel::UdpChannel(const udp::Endpoint& localEndpoint,
                        time::nanoseconds idleTimeout,
-                       bool wantCongestionMarking)
+                       bool wantCongestionMarking,
+                       size_t defaultMtu)
   : m_localEndpoint(localEndpoint)
   , m_socket(getGlobalIoService())
   , m_idleFaceTimeout(idleTimeout)
   , m_wantCongestionMarking(wantCongestionMarking)
 {
   setUri(FaceUri(m_localEndpoint));
+  setDefaultMtu(defaultMtu);
   NFD_LOG_CHAN_INFO("Creating channel");
 }
 
@@ -122,6 +124,7 @@
   try {
     FaceParams params;
     params.persistency = ndn::nfd::FACE_PERSISTENCY_ON_DEMAND;
+    params.mtu = getDefaultMtu();
     std::tie(isCreated, face) = createFace(m_remoteEndpoint, params);
   }
   catch (const boost::system::system_error& e) {
@@ -180,9 +183,7 @@
     options.defaultCongestionThreshold = *params.defaultCongestionThreshold;
   }
 
-  if (params.mtu) {
-    options.overrideMtu = *params.mtu;
-  }
+  options.overrideMtu = params.mtu.value_or(getDefaultMtu());
 
   auto linkService = make_unique<GenericLinkService>(options);
   auto transport = make_unique<UnicastUdpTransport>(std::move(socket), params.persistency,
diff --git a/daemon/face/udp-channel.hpp b/daemon/face/udp-channel.hpp
index 89540de..c3f696d 100644
--- a/daemon/face/udp-channel.hpp
+++ b/daemon/face/udp-channel.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2021,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -49,7 +49,8 @@
    */
   UdpChannel(const udp::Endpoint& localEndpoint,
              time::nanoseconds idleTimeout,
-             bool wantCongestionMarking);
+             bool wantCongestionMarking,
+             size_t defaultMtu);
 
   bool
   isListening() const override
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 993f61a..9eabd42 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2020,  Regents of the University of California,
+ * Copyright (c) 2014-2021,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -66,6 +66,7 @@
   //   enable_v4 yes
   //   enable_v6 yes
   //   idle_timeout 600
+  //   unicast_mtu 8800
   //   mcast yes
   //   mcast_group 224.0.23.170
   //   mcast_port 56363
@@ -88,6 +89,7 @@
   bool enableV4 = false;
   bool enableV6 = false;
   uint32_t idleTimeout = 600;
+  size_t unicastMtu = ndn::MAX_NDN_PACKET_SIZE;
   MulticastConfig mcastConfig;
 
   if (configSection) {
@@ -113,6 +115,11 @@
       else if (key == "idle_timeout") {
         idleTimeout = ConfigFile::parseNumber<uint32_t>(pair, "face_system.udp");
       }
+      else if (key == "unicast_mtu") {
+        unicastMtu = ConfigFile::parseNumber<size_t>(pair, "face_system.udp");
+        ConfigFile::checkRange(unicastMtu, static_cast<size_t>(MIN_MTU), ndn::MAX_NDN_PACKET_SIZE,
+                               "unicast_mtu", "face_system.udp");
+      }
       else if (key == "keep_alive_interval") {
         // ignored
       }
@@ -177,6 +184,8 @@
     return;
   }
 
+  m_defaultUnicastMtu = unicastMtu;
+
   if (enableV4) {
     udp::Endpoint endpoint(ip::udp::v4(), port);
     shared_ptr<UdpChannel> v4Channel = this->createChannel(endpoint, time::seconds(idleTimeout));
@@ -302,7 +311,8 @@
                     ", endpoint already allocated to a UDP multicast face"));
   }
 
-  auto channel = std::make_shared<UdpChannel>(localEndpoint, idleTimeout, m_wantCongestionMarking);
+  auto channel = std::make_shared<UdpChannel>(localEndpoint, idleTimeout,
+                                              m_wantCongestionMarking, m_defaultUnicastMtu);
   m_channels[localEndpoint] = channel;
   return channel;
 }
diff --git a/daemon/face/udp-factory.hpp b/daemon/face/udp-factory.hpp
index a57cb25..a0f5b6d 100644
--- a/daemon/face/udp-factory.hpp
+++ b/daemon/face/udp-factory.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018,  Regents of the University of California,
+ * Copyright (c) 2014-2021,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -123,6 +123,7 @@
 
 private:
   bool m_wantCongestionMarking = false;
+  size_t m_defaultUnicastMtu = ndn::MAX_NDN_PACKET_SIZE;
   std::map<udp::Endpoint, shared_ptr<UdpChannel>> m_channels;
 
   struct MulticastConfig