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()) {
99 BOOST_THROW_EXCEPTION(ConfigFile::Error(
"face_system.ether.mcast_group: '" +
100 valueStr +
"' cannot be parsed as an Ethernet address"));
102 else if (!mcastConfig.group.isMulticast()) {
103 BOOST_THROW_EXCEPTION(ConfigFile::Error(
"face_system.ether.mcast_group: '" +
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);
168 EthernetFactory::doCreateFace(
const CreateFaceRequest& req,
172 if (!req.localUri || req.localUri->getScheme() !=
"dev") {
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());
187 if (remoteEndpoint.isMulticast()) {
188 NFD_LOG_TRACE(
"createFace does not support multicast faces");
189 onFailure(406,
"Cannot create multicast Ethernet faces");
193 if (req.params.wantLocalFields) {
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>
220 time::nanoseconds idleTimeout)
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;
253 auto linkService = make_unique<GenericLinkService>(opts);
254 auto transport = make_unique<MulticastEthernetTransport>(netif, address, m_mcastConfig.linkType);
255 auto face = make_shared<Face>(std::move(linkService), std::move(transport));
257 m_mcastFaces[key] = face;
263 shared_ptr<EthernetChannel>
264 EthernetFactory::applyUnicastConfigToNetif(
const shared_ptr<const ndn::net::NetworkInterface>& netif)
266 if (!m_unicastConfig.isEnabled) {
275 if (!netif->
isUp()) {
285 auto channel = this->
createChannel(netif, m_unicastConfig.idleTimeout);
286 if (m_unicastConfig.wantListen && !channel->isListening()) {
288 channel->listen(this->
addFace,
nullptr);
290 catch (
const EthernetChannel::Error& e) {
300 if (!m_mcastConfig.isEnabled) {
305 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": incompatible netif type");
315 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": netif cannot multicast");
320 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": invalid Ethernet address");
324 if (!m_mcastConfig.netifPredicate(netif)) {
325 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": rejected by whitelist/blacklist");
330 shared_ptr<Face> face;
334 catch (
const EthernetTransport::Error& e) {
347 EthernetFactory::applyConfig(
const FaceSystem::ConfigContext&)
349 if (m_unicastConfig.isEnabled) {
357 std::set<shared_ptr<Face>> oldFaces;
358 boost::copy(m_mcastFaces | boost::adaptors::map_values, std::inserter(oldFaces, oldFaces.end()));
361 for (
const auto& netif :
netmon->listNetworkInterfaces()) {
362 this->applyUnicastConfigToNetif(netif);
364 auto face = this->applyMcastConfigToNetif(*netif);
365 if (face !=
nullptr) {
367 oldFaces.erase(face);
372 for (
const auto& face : oldFaces) {
std::set< std::string > providedSchemes
FaceUri schemes provided by this protocol factory.
static Address fromString(const std::string &str)
Creates an Address from a string containing an Ethernet address in hexadecimal notation,...
InterfaceType getType() const
Returns the hardware type of the interface.
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.
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)
static constexpr ssize_t MIN_MTU
minimum MTU that may be set on a transport
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...
void connectFaceClosedSignal(Face &face, const std::function< void()> &f)
invokes a callback when the 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.
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
Options that control the behavior of GenericLinkService.
ethernet::Address getEthernetAddress() const
Returns the link-layer (Ethernet) address of the interface.
std::string to_string(const V &v)
static std::vector< shared_ptr< const Channel > > getChannelsFromMap(const ChannelMap &channelMap)
static const std::string & getId() noexcept
#define NFD_LOG_INIT(name)
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