30 #include <boost/range/adaptors.hpp> 31 #include <boost/range/algorithm/copy.hpp> 42 static std::string id(
"ether");
49 m_netifAddConn =
netmon->onInterfaceAdded.connect(
50 [
this] (
const shared_ptr<const ndn::net::NetworkInterface>& netif) {
51 this->applyUnicastConfigToNetif(netif);
52 this->applyMcastConfigToNetif(*netif);
76 UnicastConfig unicastConfig;
77 MulticastConfig mcastConfig;
81 unicastConfig.isEnabled = unicastConfig.wantListen = mcastConfig.isEnabled =
true;
83 for (
const auto& pair : *configSection) {
84 const std::string& key = pair.first;
87 if (key ==
"listen") {
90 else if (key ==
"idle_timeout") {
91 unicastConfig.idleTimeout = time::seconds(ConfigFile::parseNumber<uint32_t>(pair,
"face_system.ether"));
93 else if (key ==
"mcast") {
96 else if (key ==
"mcast_group") {
97 const std::string& valueStr = value.get_value<std::string>();
99 if (mcastConfig.group.isNull()) {
101 valueStr +
"' cannot be parsed as an Ethernet address"));
103 else if (!mcastConfig.group.isMulticast()) {
105 valueStr +
"' is not a multicast address"));
108 else if (key ==
"mcast_ad_hoc") {
112 else if (key ==
"whitelist") {
113 mcastConfig.netifPredicate.parseWhitelist(value);
115 else if (key ==
"blacklist") {
116 mcastConfig.netifPredicate.parseBlacklist(value);
119 BOOST_THROW_EXCEPTION(
ConfigFile::Error(
"Unrecognized option face_system.ether." + key));
128 if (unicastConfig.isEnabled) {
129 if (m_unicastConfig.wantListen && !unicastConfig.wantListen && !m_channels.empty()) {
130 NFD_LOG_WARN(
"Cannot stop listening on Ethernet channels");
132 if (m_unicastConfig.idleTimeout != unicastConfig.idleTimeout && !m_channels.empty()) {
133 NFD_LOG_WARN(
"Idle timeout setting applies to new Ethernet channels only");
136 else if (m_unicastConfig.isEnabled && !m_channels.empty()) {
137 NFD_LOG_WARN(
"Cannot disable Ethernet channels after initialization");
140 if (m_mcastConfig.isEnabled != mcastConfig.isEnabled) {
141 if (mcastConfig.isEnabled) {
142 NFD_LOG_INFO(
"enabling multicast on " << mcastConfig.group);
148 else if (mcastConfig.isEnabled) {
149 if (m_mcastConfig.linkType != mcastConfig.linkType && !m_mcastFaces.empty()) {
150 NFD_LOG_WARN(
"Cannot change ad hoc setting on existing faces");
152 if (m_mcastConfig.group != mcastConfig.group) {
153 NFD_LOG_INFO(
"changing multicast group from " << m_mcastConfig.group <<
154 " to " << mcastConfig.group);
156 if (m_mcastConfig.netifPredicate != mcastConfig.netifPredicate) {
163 m_unicastConfig = unicastConfig;
164 m_mcastConfig = mcastConfig;
165 this->applyConfig(context);
176 NFD_LOG_TRACE(
"Cannot create unicast Ethernet face without dev:// LocalUri");
177 onFailure(406,
"Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme");
180 BOOST_ASSERT(req.
localUri->isCanonical());
183 NFD_LOG_TRACE(
"createFace does not support FACE_PERSISTENCY_ON_DEMAND");
184 onFailure(406,
"Outgoing Ethernet faces do not support on-demand persistency");
189 std::string localEndpoint(req.
localUri->getHost());
192 NFD_LOG_TRACE(
"createFace does not support multicast faces");
193 onFailure(406,
"Cannot create multicast Ethernet faces");
199 NFD_LOG_TRACE(
"createFace cannot create non-local face with local fields enabled");
200 onFailure(406,
"Local fields can only be enabled on faces with local scope");
204 for (
const auto& i : m_channels) {
205 if (i.first == localEndpoint) {
206 i.second->connect(remoteEndpoint, req.
params, 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);
288 catch (
const EthernetChannel::Error& e) {
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;
332 catch (
const EthernetTransport::Error& e) {
345 EthernetFactory::applyConfig(
const FaceSystem::ConfigContext& context)
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.
InterfaceType getType() const
Returns the hardware type of the interface.
bool allowReassembly
enables reassembly
const std::string & getHost() const
get host (domain)
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.
std::string getName() const
Returns the name of the interface, unique on the system.
bool isNull() const
True if this is a null address (00:00:00:00:00:00)
#define NFD_LOG_DEBUG(expression)
NFD_REGISTER_PROTOCOL_FACTORY(EthernetFactory)
std::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::optional< const ConfigSection & > OptionalConfigSection
an optional config file section
std::function< void(const shared_ptr< Face > &face)> FaceCreatedCallback
Prototype for the callback that is invoked when a face is created (in response to an incoming connect...
#define NFD_LOG_INFO(expression)
void connectFaceClosedSignal(Face &face, const std::function< void()> &f)
invokes a callback when the face is closed
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.
#define NFD_LOG_TRACE(expression)
Provides support for an underlying protocol.
Copyright (c) 2011-2015 Regents of the University of California.
EthernetFactory(const CtorParams ¶ms)
bool canMulticast() const
Returns true if the interface supports multicast communication.
bool isUp() const
Returns true if the interface is administratively up.
protocol factory for Ethernet
Parameters to ProtocolFactory constructor.
boost::property_tree::ptree ConfigSection
a config file section
ndn::nfd::FacePersistency persistency
shared_ptr< Face > createMulticastFace(const ndn::net::NetworkInterface &localEndpoint, const ethernet::Address &group)
Create a face to communicate on the given Ethernet multicast group.
bool isMulticast() const
True if this is a multicast address.
context for processing a config section in ProtocolFactory
represents an Ethernet hardware address
Options that control the behavior of GenericLinkService.
#define NFD_LOG_WARN(expression)
static const std::string & getId()
Encapsulates a face creation request and all its parameters.
optional< FaceUri > localUri
ethernet::Address getEthernetAddress() const
Returns the link-layer (Ethernet) address of the interface.
static std::vector< shared_ptr< const Channel > > getChannelsFromMap(const ChannelMap &channelMap)
bool isCanonical() const
determine whether this FaceUri is in canonical form
#define NFD_LOG_INIT(name)
void createFace(const CreateFaceRequest &req, const FaceCreatedCallback &onCreated, const FaceCreationFailedCallback &onFailure) override
Try to create a unicast face using the supplied parameters.
const FaceId INVALID_FACEID
indicates an invalid FaceId
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