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>();
97 mcastConfig.group = ethernet::Address::fromString(valueStr);
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") {
109 mcastConfig.linkType = wantAdHoc ? ndn::nfd::LINK_TYPE_AD_HOC : ndn::nfd::LINK_TYPE_MULTI_ACCESS;
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);
172 BOOST_ASSERT(params.
remoteUri.isCanonical());
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());
181 if (params.
persistency == ndn::nfd::FACE_PERSISTENCY_ON_DEMAND) {
182 NFD_LOG_TRACE(
"createFace does not support FACE_PERSISTENCY_ON_DEMAND");
183 onFailure(406,
"Outgoing Ethernet faces do not support on-demand persistency");
187 ethernet::Address remoteEndpoint(ethernet::Address::fromString(params.
remoteUri.getHost()));
188 std::string localEndpoint(params.
localUri->getHost());
190 if (remoteEndpoint.isMulticast()) {
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>>
237 const ethernet::Address& address)
239 BOOST_ASSERT(address.isMulticast());
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) {
268 if (netif->getType() != ndn::net::InterfaceType::ETHERNET) {
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());
296 EthernetFactory::applyMcastConfigToNetif(
const ndn::net::NetworkInterface& netif)
298 if (!m_mcastConfig.isEnabled) {
302 if (netif.getType() != ndn::net::InterfaceType::ETHERNET) {
303 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.getName() <<
": incompatible netif type");
308 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.getName() <<
": netif is down");
312 if (!netif.canMulticast()) {
313 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.getName() <<
": netif cannot multicast");
317 if (netif.getEthernetAddress().isNull()) {
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");
327 NFD_LOG_DEBUG(
"Creating multicast face on " << netif.getName());
328 shared_ptr<Face> face;
333 NFD_LOG_WARN(
"Cannot create multicast face on " << netif.getName() <<
": " << e.what());
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) {
FaceCreatedCallback addFace
callback when a new face is created
#define NFD_LOG_DEBUG(expression)
bool allowFragmentation
enables fragmentation
void createFace(const CreateFaceParams ¶ms, const FaceCreatedCallback &onCreated, const FaceCreationFailedCallback &onFailure) override
Try to create face using the supplied parameters.
std::set< std::string > providedSchemes
FaceUri schemes provided by this ProtocolFactory.
std::vector< shared_ptr< const Channel > > getChannels() const override
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_REGISTER_PROTOCOL_FACTORY(PF)
registers a protocol factory
void connectFaceClosedSignal(Face &face, const std::function< void()> &f)
invokes a callback when the face is closed
EthernetChannel-related error.
#define NFD_LOG_WARN(expression)
ndn::nfd::FacePersistency persistency
ndn::optional< FaceUri > localUri
context for processing a config section in ProtocolFactory
static std::vector< shared_ptr< const Channel > > getChannelsFromMap(const ChannelMap &channelMap)
#define NFD_LOG_INFO(expression)
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
boost::optional< const ConfigSection & > OptionalConfigSection
an optional config file section
static const std::string & getId()
boost::property_tree::ptree ConfigSection
a config file section
function< void(uint32_t status, const std::string &reason)> FaceCreationFailedCallback
Prototype for the callback that is invoked when a face fails to be created.
shared_ptr< EthernetChannel > createChannel(const shared_ptr< const ndn::net::NetworkInterface > &localEndpoint, time::nanoseconds idleTimeout)
Create Ethernet-based channel on the specified network interface.
Provides support for an underlying protocol.
Options that control the behavior of GenericLinkService.
Parameters to ProtocolFactory constructor.
shared_ptr< Face > createMulticastFace(const ndn::net::NetworkInterface &localEndpoint, const ethernet::Address &group)
Create a face to communicate on the given Ethernet multicast group.
#define NFD_LOG_INIT(name)
#define NFD_LOG_TRACE(expression)
void processConfig(OptionalConfigSection configSection, FaceSystem::ConfigContext &context) override
process face_system.ether config section
Parameters to ProtocolFactory::createFace.
EthernetFactory(const CtorParams ¶ms)
const FaceId INVALID_FACEID
indicates an invalid FaceId
bool allowReassembly
enables reassembly
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...