29 #include <boost/range/adaptors.hpp> 30 #include <boost/range/algorithm/copy.hpp> 41 static std::string id(
"ether");
48 m_netifAddConn =
netmon->onInterfaceAdded.connect(
49 [
this] (
const shared_ptr<const ndn::net::NetworkInterface>& netif) {
50 this->applyUnicastConfigToNetif(netif);
51 this->applyMcastConfigToNetif(*netif);
75 UnicastConfig unicastConfig;
76 MulticastConfig mcastConfig;
80 unicastConfig.isEnabled = unicastConfig.wantListen = mcastConfig.isEnabled =
true;
82 for (
const auto& pair : *configSection) {
83 const std::string& key = pair.first;
86 if (key ==
"listen") {
89 else if (key ==
"idle_timeout") {
90 unicastConfig.idleTimeout = time::seconds(ConfigFile::parseNumber<uint32_t>(pair,
"face_system.ether"));
92 else if (key ==
"mcast") {
95 else if (key ==
"mcast_group") {
96 const std::string& valueStr = value.get_value<std::string>();
98 if (mcastConfig.group.isNull()) {
100 valueStr +
"' cannot be parsed as an Ethernet address"));
102 else if (!mcastConfig.group.isMulticast()) {
104 valueStr +
"' is not a multicast address"));
107 else if (key ==
"mcast_ad_hoc") {
111 else if (key ==
"whitelist") {
112 mcastConfig.netifPredicate.parseWhitelist(value);
114 else if (key ==
"blacklist") {
115 mcastConfig.netifPredicate.parseBlacklist(value);
118 BOOST_THROW_EXCEPTION(
ConfigFile::Error(
"Unrecognized option face_system.ether." + key));
127 if (unicastConfig.isEnabled) {
128 if (m_unicastConfig.wantListen && !unicastConfig.wantListen && !m_channels.empty()) {
129 NFD_LOG_WARN(
"Cannot stop listening on Ethernet channels");
131 if (m_unicastConfig.idleTimeout != unicastConfig.idleTimeout && !m_channels.empty()) {
132 NFD_LOG_WARN(
"Idle timeout setting applies to new Ethernet channels only");
135 else if (m_unicastConfig.isEnabled && !m_channels.empty()) {
136 NFD_LOG_WARN(
"Cannot disable Ethernet channels after initialization");
139 if (m_mcastConfig.isEnabled != mcastConfig.isEnabled) {
140 if (mcastConfig.isEnabled) {
141 NFD_LOG_INFO(
"enabling multicast on " << mcastConfig.group);
147 else if (mcastConfig.isEnabled) {
148 if (m_mcastConfig.linkType != mcastConfig.linkType && !m_mcastFaces.empty()) {
149 NFD_LOG_WARN(
"Cannot change ad hoc setting on existing faces");
151 if (m_mcastConfig.group != mcastConfig.group) {
152 NFD_LOG_INFO(
"changing multicast group from " << m_mcastConfig.group <<
153 " to " << mcastConfig.group);
155 if (m_mcastConfig.netifPredicate != mcastConfig.netifPredicate) {
162 m_unicastConfig = unicastConfig;
163 m_mcastConfig = mcastConfig;
164 this->applyConfig(context);
175 NFD_LOG_TRACE(
"Cannot create unicast Ethernet face without dev:// LocalUri");
176 onFailure(406,
"Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme");
179 BOOST_ASSERT(params.
localUri->isCanonical());
182 NFD_LOG_TRACE(
"createFace does not support FACE_PERSISTENCY_ON_DEMAND");
183 onFailure(406,
"Outgoing Ethernet faces do not support on-demand persistency");
188 std::string localEndpoint(params.
localUri->getHost());
191 NFD_LOG_TRACE(
"createFace does not support multicast faces");
192 onFailure(406,
"Cannot create multicast Ethernet faces");
198 NFD_LOG_TRACE(
"createFace cannot create non-local face with local fields enabled");
199 onFailure(406,
"Local fields can only be enabled on faces with local scope");
203 for (
const auto& i : m_channels) {
204 if (i.first == localEndpoint) {
206 onCreated, onFailure);
211 NFD_LOG_TRACE(
"No channels available to connect to " << remoteEndpoint);
212 onFailure(504,
"No channels available to connect");
215 shared_ptr<EthernetChannel>
217 time::nanoseconds idleTimeout)
219 auto it = m_channels.find(localEndpoint->getName());
220 if (it != m_channels.end())
223 auto channel = std::make_shared<EthernetChannel>(localEndpoint, idleTimeout);
224 m_channels[localEndpoint->getName()] = channel;
229 std::vector<shared_ptr<const Channel>>
241 auto key = std::make_pair(netif.
getName(), address);
242 auto found = m_mcastFaces.find(key);
243 if (found != m_mcastFaces.end()) {
244 return found->second;
251 auto linkService = make_unique<GenericLinkService>(opts);
252 auto transport = make_unique<MulticastEthernetTransport>(netif, address, m_mcastConfig.linkType);
253 auto face = make_shared<Face>(std::move(linkService), std::move(transport));
255 m_mcastFaces[key] = face;
261 shared_ptr<EthernetChannel>
262 EthernetFactory::applyUnicastConfigToNetif(
const shared_ptr<const ndn::net::NetworkInterface>& netif)
264 if (!m_unicastConfig.isEnabled) {
269 NFD_LOG_DEBUG(
"Not creating channel on " << netif->getName() <<
": incompatible netif type");
273 if (!netif->isUp()) {
274 NFD_LOG_DEBUG(
"Not creating channel on " << netif->getName() <<
": netif is down");
278 if (netif->getEthernetAddress().isNull()) {
279 NFD_LOG_DEBUG(
"Not creating channel on " << netif->getName() <<
": invalid Ethernet address");
283 auto channel = this->
createChannel(netif, m_unicastConfig.idleTimeout);
284 if (m_unicastConfig.wantListen && !channel->isListening()) {
286 channel->listen(this->
addFace,
nullptr);
289 NFD_LOG_WARN(
"Cannot listen on " << netif->getName() <<
": " << e.what());
298 if (!m_mcastConfig.isEnabled) {
303 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": incompatible netif type");
313 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": netif cannot multicast");
318 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": invalid Ethernet address");
322 if (!m_mcastConfig.netifPredicate(netif)) {
323 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": rejected by whitelist/blacklist");
328 shared_ptr<Face>
face;
347 if (m_unicastConfig.isEnabled) {
355 std::set<shared_ptr<Face>> oldFaces;
356 boost::copy(m_mcastFaces | boost::adaptors::map_values, std::inserter(oldFaces, oldFaces.end()));
359 for (
const auto& netif :
netmon->listNetworkInterfaces()) {
360 this->applyUnicastConfigToNetif(netif);
362 auto face = this->applyMcastConfigToNetif(*netif);
363 if (
face !=
nullptr) {
365 oldFaces.erase(
face);
370 for (
const auto&
face : oldFaces) {
std::set< std::string > providedSchemes
FaceUri schemes provided by this ProtocolFactory.
static Address fromString(const std::string &str)
Creates an Address from a string containing an Ethernet address in hexadecimal notation, with colons or hyphens as separators.
bool allowReassembly
enables reassembly
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"
shared_ptr< ndn::net::NetworkMonitor > netmon
NetworkMonitor for listing available network interfaces and monitoring their changes.
void createFace(const CreateFaceParams ¶ms, const FaceCreatedCallback &onCreated, const FaceCreationFailedCallback &onFailure) override
Try to create face using the supplied parameters.
ndn::nfd::FacePersistency persistency
bool canMulticast() const
Returns true if the interface supports multicast communication.
#define NFD_LOG_DEBUG(expression)
NFD_REGISTER_PROTOCOL_FACTORY(EthernetFactory)
#define NFD_LOG_INFO(expression)
void connectFaceClosedSignal(Face &face, const std::function< void()> &f)
invokes a callback when the face is closed
Parameters to ProtocolFactory::createFace.
std::vector< shared_ptr< const Channel > > getChannels() const override
void processConfig(OptionalConfigSection configSection, FaceSystem::ConfigContext &context) override
process face_system.ether config section
FaceCreatedCallback addFace
callback when a new face is created
Represents one network interface attached to the host.
ndn::optional< FaceUri > localUri
#define NFD_LOG_TRACE(expression)
Provides support for an underlying protocol.
EthernetChannel-related error.
InterfaceType getType() const
Returns the hardware type of the interface.
Copyright (c) 2011-2015 Regents of the University of California.
EthernetFactory(const CtorParams ¶ms)
boost::optional< const ConfigSection & > OptionalConfigSection
an optional config file section
protocol factory for Ethernet
Parameters to ProtocolFactory constructor.
boost::property_tree::ptree ConfigSection
a config file section
bool isMulticast() const
True if this is a multicast address.
shared_ptr< Face > createMulticastFace(const ndn::net::NetworkInterface &localEndpoint, const ethernet::Address &group)
Create a face to communicate on the given Ethernet multicast group.
std::string getName() const
Returns the name of the interface, unique on the system.
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.
represents an Ethernet hardware address
Options that control the behavior of GenericLinkService.
#define NFD_LOG_WARN(expression)
bool isCanonical() const
determine whether this FaceUri is in canonical form
bool isUp() const
Returns true if the interface is administratively up.
static const std::string & getId()
bool isNull() const
True if this is a null address (00:00:00:00:00:00)
ethernet::Address getEthernetAddress() const
Returns the link-layer (Ethernet) address of the interface.
static std::vector< shared_ptr< const Channel > > getChannelsFromMap(const ChannelMap &channelMap)
const std::string & getHost() const
get host (domain)
#define NFD_LOG_INIT(name)
const FaceId INVALID_FACEID
indicates an invalid FaceId
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...
shared_ptr< EthernetChannel > createChannel(const shared_ptr< const ndn::net::NetworkInterface > &localEndpoint, time::nanoseconds idleTimeout)
Create Ethernet-based channel on the specified network interface.
bool allowFragmentation
enables fragmentation