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([
this] (
const auto& 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);
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);
173 NFD_LOG_TRACE(
"Cannot create unicast Ethernet face without dev:// LocalUri");
174 onFailure(406,
"Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme");
179 NFD_LOG_TRACE(
"createFace does not support FACE_PERSISTENCY_ON_DEMAND");
180 onFailure(406,
"Outgoing Ethernet faces do not support on-demand persistency");
185 std::string localEndpoint(req.
localUri->getHost());
188 NFD_LOG_TRACE(
"createFace does not support multicast faces");
189 onFailure(406,
"Cannot create multicast Ethernet faces");
195 NFD_LOG_TRACE(
"createFace cannot create non-local face with local fields enabled");
196 onFailure(406,
"Local fields can only be enabled on faces with local scope");
207 for (
const auto& i : m_channels) {
208 if (i.first == localEndpoint) {
209 i.second->connect(remoteEndpoint, req.
params, onCreated, onFailure);
214 NFD_LOG_TRACE(
"No channels available to connect to " << remoteEndpoint);
215 onFailure(504,
"No channels available to connect");
218 shared_ptr<EthernetChannel>
222 auto it = m_channels.find(localEndpoint->getName());
223 if (it != m_channels.end())
226 auto channel = std::make_shared<EthernetChannel>(localEndpoint, idleTimeout);
227 m_channels[localEndpoint->getName()] = channel;
231 std::vector<shared_ptr<const Channel>>
232 EthernetFactory::doGetChannels()
const 243 auto key = std::make_pair(netif.
getName(), address);
244 auto found = m_mcastFaces.find(key);
245 if (found != m_mcastFaces.end()) {
246 return found->second;
249 GenericLinkService::Options opts;
250 opts.allowFragmentation =
true;
251 opts.allowReassembly =
true;
253 auto linkService = make_unique<GenericLinkService>(opts);
254 auto transport = make_unique<MulticastEthernetTransport>(netif, address, m_mcastConfig.linkType);
257 m_mcastFaces[key] = face;
260 auto channelIt = m_channels.find(netif.getName());
261 face->setChannel(channelIt != m_channels.end() ? channelIt->second :
nullptr);
266 shared_ptr<EthernetChannel>
267 EthernetFactory::applyUnicastConfigToNetif(
const shared_ptr<const ndn::net::NetworkInterface>& netif)
269 if (!m_unicastConfig.isEnabled) {
274 NFD_LOG_DEBUG(
"Not creating channel on " << netif->getName() <<
": incompatible netif type");
278 if (!netif->isUp()) {
279 NFD_LOG_DEBUG(
"Not creating channel on " << netif->getName() <<
": netif is down");
283 if (netif->getEthernetAddress().isNull()) {
284 NFD_LOG_DEBUG(
"Not creating channel on " << netif->getName() <<
": invalid Ethernet address");
288 auto channel = this->
createChannel(netif, m_unicastConfig.idleTimeout);
289 if (m_unicastConfig.wantListen && !channel->isListening()) {
291 channel->listen(this->
addFace,
nullptr);
294 NFD_LOG_WARN(
"Cannot listen on " << netif->getName() <<
": " << e.what());
303 if (!m_mcastConfig.isEnabled) {
308 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": incompatible netif type");
318 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": netif cannot multicast");
323 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": invalid Ethernet address");
327 if (!m_mcastConfig.netifPredicate(netif)) {
328 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": rejected by whitelist/blacklist");
333 shared_ptr<Face> face;
352 if (m_unicastConfig.isEnabled) {
360 std::set<shared_ptr<Face>> oldFaces;
361 boost::copy(m_mcastFaces | boost::adaptors::map_values, std::inserter(oldFaces, oldFaces.end()));
364 for (
const auto& netif :
netmon->listNetworkInterfaces()) {
365 this->applyUnicastConfigToNetif(netif);
367 auto face = this->applyMcastConfigToNetif(*netif);
368 if (face !=
nullptr) {
370 oldFaces.erase(face);
375 for (
const auto& face : oldFaces) {
std::set< std::string > providedSchemes
FaceUri schemes provided by this protocol factory.
boost::chrono::seconds seconds
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.
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.
#define NFD_LOG_INIT(name)
std::string to_string(const T &val)
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)
ndn::nfd::FacePersistency persistency
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
void connectFaceClosedSignal(Face &face, std::function< void()> f)
Invokes a callback when a face is closed.
FaceCreatedCallback addFace
callback when a new face is created
Represents one network interface attached to the host.
Provides support for an underlying protocol.
EthernetChannel-related error.
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
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
Encapsulates a face creation request and all its parameters.
optional< FaceUri > localUri
std::function< void(const shared_ptr< Face > &)> FaceCreatedCallback
Prototype for the callback that is invoked when a face is created (in response to an incoming connect...
ethernet::Address getEthernetAddress() const
Returns the link-layer (Ethernet) address of the interface.
const ssize_t MIN_MTU
Minimum MTU that may be set.
static std::vector< shared_ptr< const Channel > > getChannelsFromMap(const ChannelMap &channelMap)
static const std::string & getId() noexcept
const FaceId INVALID_FACEID
indicates an invalid FaceId
boost::chrono::nanoseconds nanoseconds
shared_ptr< EthernetChannel > createChannel(const shared_ptr< const ndn::net::NetworkInterface > &localEndpoint, time::nanoseconds idleTimeout)
Create Ethernet-based channel on the specified network interface.