31 #include <ndn-cxx/net/address-converter.hpp>    32 #include <boost/range/adaptors.hpp>    33 #include <boost/range/algorithm/copy.hpp>    38 #include <sys/socket.h>     52   static std::string id(
"udp");
    59   m_netifAddConn = 
netmon->onInterfaceAdded.connect(bind(&UdpFactory::applyMcastConfigToNetif, 
this, _1));
    87   bool enableV4 = 
false;
    88   bool enableV6 = 
false;
    89   uint32_t idleTimeout = 600;
    90   MulticastConfig mcastConfig;
    94     enableV4 = enableV6 = mcastConfig.isEnabled = 
true;
    96     for (
const auto& pair : *configSection) {
    97       const std::string& key = pair.first;
   101         port = ConfigFile::parseNumber<uint16_t>(pair, 
"face_system.udp");
   103       else if (key == 
"enable_v4") {
   106       else if (key == 
"enable_v6") {
   109       else if (key == 
"idle_timeout") {
   110         idleTimeout = ConfigFile::parseNumber<uint32_t>(pair, 
"face_system.udp");
   112       else if (key == 
"keep_alive_interval") {
   115       else if (key == 
"mcast") {
   118       else if (key == 
"mcast_group") {
   119         const std::string& valueStr = value.get_value<std::string>();
   120         boost::system::error_code ec;
   121         mcastConfig.group.address(boost::asio::ip::address_v4::from_string(valueStr, ec));
   124                                 valueStr + 
"' cannot be parsed as an IPv4 address"));
   126         else if (!mcastConfig.group.address().is_multicast()) {
   128                                 valueStr + 
"' is not a multicast address"));
   131       else if (key == 
"mcast_port") {
   132         mcastConfig.group.port(ConfigFile::parseNumber<uint16_t>(pair, 
"face_system.udp"));
   134       else if (key == 
"mcast_ad_hoc") {
   138       else if (key == 
"whitelist") {
   139         mcastConfig.netifPredicate.parseWhitelist(value);
   141       else if (key == 
"blacklist") {
   142         mcastConfig.netifPredicate.parseBlacklist(value);
   145         BOOST_THROW_EXCEPTION(
ConfigFile::Error(
"Unrecognized option face_system.udp." + key));
   149     if (!enableV4 && !enableV6 && !mcastConfig.isEnabled) {
   151         "IPv4 and IPv6 UDP channels and UDP multicast have been disabled. "   152         "Remove face_system.udp section to disable UDP channels or enable at least one of them."));
   162     shared_ptr<UdpChannel> v4Channel = this->
createChannel(endpoint, time::seconds(idleTimeout));
   163     if (!v4Channel->isListening()) {
   164       v4Channel->listen(this->
addFace, 
nullptr);
   170     NFD_LOG_WARN(
"Cannot close udp4 channel after its creation");
   175     shared_ptr<UdpChannel> v6Channel = this->
createChannel(endpoint, time::seconds(idleTimeout));
   176     if (!v6Channel->isListening()) {
   177       v6Channel->listen(this->
addFace, 
nullptr);
   183     NFD_LOG_WARN(
"Cannot close udp6 channel after its creation");
   186   if (m_mcastConfig.isEnabled != mcastConfig.isEnabled) {
   187     if (mcastConfig.isEnabled) {
   188       NFD_LOG_INFO(
"enabling multicast on " << mcastConfig.group);
   194   else if (mcastConfig.isEnabled) {
   195     if (m_mcastConfig.linkType != mcastConfig.linkType && !m_mcastFaces.empty()) {
   196       NFD_LOG_WARN(
"Cannot change ad hoc setting on existing faces");
   198     if (m_mcastConfig.group != mcastConfig.group) {
   199       NFD_LOG_INFO(
"changing multicast group from " << m_mcastConfig.group <<
   200                    " to " << mcastConfig.group);
   202     if (m_mcastConfig.netifPredicate != mcastConfig.netifPredicate) {
   209   m_mcastConfig = mcastConfig;
   210   this->applyMcastConfig(context);
   221     NFD_LOG_TRACE(
"Cannot create unicast UDP face with LocalUri");
   222     onFailure(406, 
"Unicast UDP faces cannot be created with a LocalUri");
   227     NFD_LOG_TRACE(
"createFace does not support FACE_PERSISTENCY_ON_DEMAND");
   228     onFailure(406, 
"Outgoing UDP faces do not support on-demand persistency");
   235   if (endpoint.address().is_multicast()) {
   236     NFD_LOG_TRACE(
"createFace does not support multicast faces");
   237     onFailure(406, 
"Cannot create multicast UDP faces");
   243     NFD_LOG_TRACE(
"createFace cannot create non-local face with local fields enabled");
   244     onFailure(406, 
"Local fields can only be enabled on faces with local scope");
   249   for (
const auto& i : m_channels) {
   250     if ((i.first.address().is_v4() && endpoint.address().is_v4()) ||
   251         (i.first.address().is_v6() && endpoint.address().is_v6())) {
   253                         onCreated, onFailure);
   258   NFD_LOG_TRACE(
"No channels available to connect to " << endpoint);
   259   onFailure(504, 
"No channels available to connect");
   262 shared_ptr<UdpChannel>
   264                           time::nanoseconds idleTimeout)
   266   auto it = m_channels.find(localEndpoint);
   267   if (it != m_channels.end())
   270   if (localEndpoint.address().is_multicast()) {
   271     BOOST_THROW_EXCEPTION(
Error(
"createChannel is only for unicast channels. The provided endpoint "   272                                 "is multicast. Use createMulticastFace to create a multicast face"));
   276   if (m_mcastFaces.find(localEndpoint) != m_mcastFaces.end()) {
   277     BOOST_THROW_EXCEPTION(
Error(
"Cannot create the requested UDP unicast channel, local "   278                                 "endpoint is already allocated for a UDP multicast face"));
   281   auto channel = std::make_shared<UdpChannel>(localEndpoint, idleTimeout);
   282   m_channels[localEndpoint] = channel;
   287 std::vector<shared_ptr<const Channel>>
   296                                 const std::string& networkInterfaceName)
   299   auto it = m_mcastFaces.find(localEndpoint);
   300   if (it != m_mcastFaces.end()) {
   301     if (it->second->getRemoteUri() == 
FaceUri(multicastEndpoint))
   304       BOOST_THROW_EXCEPTION(
Error(
"Cannot create the requested UDP multicast face, local "   305                                   "endpoint is already allocated for a UDP multicast face "   306                                   "on a different multicast group"));
   310   if (m_channels.find(localEndpoint) != m_channels.end()) {
   311     BOOST_THROW_EXCEPTION(
Error(
"Cannot create the requested UDP multicast face, local "   312                                 "endpoint is already allocated for a UDP unicast channel"));
   315   if (localEndpoint.address().is_v6() || multicastEndpoint.address().is_v6()) {
   316     BOOST_THROW_EXCEPTION(
Error(
"IPv6 multicast is not supported yet. Please provide an IPv4 "   320   if (localEndpoint.port() != multicastEndpoint.port()) {
   321     BOOST_THROW_EXCEPTION(
Error(
"Cannot create the requested UDP multicast face, "   322                                 "both endpoints should have the same port number. "));
   325   if (!multicastEndpoint.address().is_multicast()) {
   326     BOOST_THROW_EXCEPTION(
Error(
"Cannot create the requested UDP multicast face, "   327                                 "the multicast group given as input is not a multicast address"));
   331   receiveSocket.open(multicastEndpoint.protocol());
   332   receiveSocket.set_option(ip::udp::socket::reuse_address(
true));
   333   receiveSocket.bind(multicastEndpoint);
   336   sendSocket.open(multicastEndpoint.protocol());
   337   sendSocket.set_option(ip::udp::socket::reuse_address(
true));
   338   sendSocket.set_option(ip::multicast::enable_loopback(
false));
   339   sendSocket.bind(
udp::Endpoint(ip::address_v4::any(), multicastEndpoint.port()));
   340   if (localEndpoint.address() != ip::address_v4::any())
   341     sendSocket.set_option(ip::multicast::outbound_interface(localEndpoint.address().to_v4()));
   343   sendSocket.set_option(ip::multicast::join_group(multicastEndpoint.address().to_v4(),
   344                                                   localEndpoint.address().to_v4()));
   345   receiveSocket.set_option(ip::multicast::join_group(multicastEndpoint.address().to_v4(),
   346                                                      localEndpoint.address().to_v4()));
   355   if (!networkInterfaceName.empty()) {
   356     if (::setsockopt(receiveSocket.native_handle(), SOL_SOCKET, SO_BINDTODEVICE,
   357                      networkInterfaceName.c_str(), networkInterfaceName.size() + 1) < 0) {
   358       BOOST_THROW_EXCEPTION(
Error(
"Cannot bind multicast face to " + networkInterfaceName +
   359                                   ": " + std::strerror(errno)));
   364   auto linkService = make_unique<GenericLinkService>();
   365   auto transport = make_unique<MulticastUdpTransport>(localEndpoint, multicastEndpoint,
   366                                                       std::move(receiveSocket),
   367                                                       std::move(sendSocket),
   368                                                       m_mcastConfig.linkType);
   369   auto face = make_shared<Face>(std::move(linkService), std::move(transport));
   371   m_mcastFaces[localEndpoint] = face;
   379                                 const std::string& multicastIp,
   380                                 const std::string& multicastPort,
   381                                 const std::string& networkInterfaceName)
   384                               boost::lexical_cast<uint16_t>(multicastPort));
   386                                   boost::lexical_cast<uint16_t>(multicastPort));
   395     if (na.getFamily() == AddressFamily::V4 && na.getScope() != AddressScope::NOWHERE) {
   403 UdpFactory::applyMcastConfigToNetif(
const shared_ptr<const ndn::net::NetworkInterface>& netif)
   405   if (!m_mcastConfig.isEnabled) {
   409   if (!netif->isUp()) {
   410     NFD_LOG_DEBUG(
"Not creating multicast face on " << netif->getName() << 
": netif is down");
   414   if (!netif->canMulticast()) {
   415     NFD_LOG_DEBUG(
"Not creating multicast face on " << netif->getName() << 
": netif cannot multicast");
   421     NFD_LOG_DEBUG(
"Not creating multicast face on " << netif->getName() << 
": no IPv4 address");
   423     m_netifConns[netif->getIndex()].addrAddConn =
   424       netif->onAddressAdded.connectSingleShot(bind(&UdpFactory::applyMcastConfigToNetif, 
this, netif));
   428   if (!m_mcastConfig.netifPredicate(*netif)) {
   429     NFD_LOG_DEBUG(
"Not creating multicast face on " << netif->getName() << 
": rejected by whitelist/blacklist");
   433   NFD_LOG_DEBUG(
"Creating multicast face on " << netif->getName());
   434   udp::Endpoint localEndpoint(address->getIp(), m_mcastConfig.group.port());
   450   std::set<shared_ptr<Face>> oldFaces;
   451   boost::copy(m_mcastFaces | boost::adaptors::map_values, std::inserter(oldFaces, oldFaces.end()));
   454   for (
const auto& netif : 
netmon->listNetworkInterfaces()) {
   455     auto face = this->applyMcastConfigToNetif(netif);
   456     if (
face != 
nullptr) {
   458       oldFaces.erase(
face);
   463   for (
const auto& 
face : oldFaces) {
 std::set< std::string > providedSchemes
FaceUri schemes provided by this ProtocolFactory. 
 
constexpr nullopt_t nullopt
 
static bool parseYesNo(const ConfigSection &node, const std::string &key, const std::string §ionName)
parse a config option that can be either "yes" or "no" 
 
std::vector< shared_ptr< const Channel > > getChannels() const override
 
shared_ptr< ndn::net::NetworkMonitor > netmon
NetworkMonitor for listing available network interfaces and monitoring their changes. 
 
ndn::nfd::FacePersistency persistency
 
detail::SimulatorIo & getGlobalIoService()
 
#define NFD_LOG_DEBUG(expression)
 
NFD_REGISTER_PROTOCOL_FACTORY(EthernetFactory)
 
static const std::string & getId()
 
#define NFD_LOG_INFO(expression)
 
void connectFaceClosedSignal(Face &face, const std::function< void()> &f)
invokes a callback when the face is closed 
 
protocol factory for UDP over IPv4 and IPv6 
 
Parameters to ProtocolFactory::createFace. 
 
FaceCreatedCallback addFace
callback when a new face is created 
 
shared_ptr< Face > createMulticastFace(const udp::Endpoint &localEndpoint, const udp::Endpoint &multicastEndpoint, const std::string &networkInterfaceName="")
Create multicast UDP face using udp::Endpoint. 
 
Represents one network interface attached to the host. 
 
ndn::optional< FaceUri > localUri
 
#define NFD_LOG_TRACE(expression)
 
Stores one IP address supported by a network interface. 
 
Provides support for an underlying protocol. 
 
void processConfig(OptionalConfigSection configSection, FaceSystem::ConfigContext &context) override
process face_system.udp config section 
 
void createFace(const CreateFaceParams ¶ms, const FaceCreatedCallback &onCreated, const FaceCreationFailedCallback &onFailure) override
Try to create face using the supplied parameters. 
 
Copyright (c) 2011-2015 Regents of the University of California. 
 
boost::optional< const ConfigSection & > OptionalConfigSection
an optional config file section 
 
shared_ptr< UdpChannel > createChannel(const udp::Endpoint &localEndpoint, time::nanoseconds idleTimeout)
Create UDP-based channel using udp::Endpoint. 
 
Parameters to ProtocolFactory constructor. 
 
boost::property_tree::ptree ConfigSection
a config file section 
 
represents the underlying protocol and address used by a Face 
 
const std::set< NetworkAddress > & getNetworkAddresses() const 
Returns a list of all network-layer addresses present on the interface. 
 
context for processing a config section in ProtocolFactory 
 
function< void(uint32_t status, const std::string &reason)> FaceCreationFailedCallback
Prototype for the callback that is invoked when a face fails to be created. 
 
boost::asio::ip::udp::endpoint Endpoint
 
boost::asio::ip::address addressFromString(const std::string &address, boost::system::error_code &ec)
parse and convert the input string into an IP address 
 
static ndn::optional< ndn::net::NetworkAddress > getV4Address(const ndn::net::NetworkInterface &netif)
 
#define NFD_LOG_WARN(expression)
 
bool isCanonical() const 
determine whether this FaceUri is in canonical form 
 
static std::vector< shared_ptr< const Channel > > getChannelsFromMap(const ChannelMap &channelMap)
 
const std::string & getHost() const 
get host (domain) 
 
Catch-all error for socket component errors that don't fit in other categories. 
 
const std::string & getPort() const 
get port 
 
#define NFD_LOG_INIT(name)
 
const FaceId INVALID_FACEID
indicates an invalid FaceId 
 
UdpFactory(const CtorParams ¶ms)
 
function< void(const shared_ptr< Face > &newFace)> FaceCreatedCallback
Prototype for the callback that is invoked when a face is created (in response to an incoming connect...