NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
face-uri.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2018 Regents of the University of California,
4  * Arizona Board of Regents,
5  * Colorado State University,
6  * University Pierre & Marie Curie, Sorbonne University,
7  * Washington University in St. Louis,
8  * Beijing Institute of Technology,
9  * The University of Memphis.
10  *
11  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
12  *
13  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
14  * terms of the GNU Lesser General Public License as published by the Free Software
15  * Foundation, either version 3 of the License, or (at your option) any later version.
16  *
17  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
18  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
19  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
20  *
21  * You should have received copies of the GNU General Public License and GNU Lesser
22  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
23  * <http://www.gnu.org/licenses/>.
24  *
25  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
26  */
27 
28 #include "face-uri.hpp"
29 
30 #include "address-converter.hpp"
31 #include "dns.hpp"
32 #include "util/string-helper.hpp"
33 
34 #include <boost/algorithm/string.hpp>
35 #include <boost/lexical_cast.hpp>
36 #include <boost/mpl/vector.hpp>
37 #include <boost/mpl/for_each.hpp>
38 #include <boost/regex.hpp>
39 #include <set>
40 #include <sstream>
41 
42 namespace ndn {
43 
44 BOOST_CONCEPT_ASSERT((boost::EqualityComparable<FaceUri>));
45 
47  : m_isV6(false)
48 {
49 }
50 
51 FaceUri::FaceUri(const std::string& uri)
52 {
53  if (!parse(uri)) {
54  BOOST_THROW_EXCEPTION(Error("Malformed URI: " + uri));
55  }
56 }
57 
58 FaceUri::FaceUri(const char* uri)
59  : FaceUri(std::string(uri))
60 {
61 }
62 
63 bool
64 FaceUri::parse(const std::string& uri)
65 {
66  m_scheme.clear();
67  m_host.clear();
68  m_port.clear();
69  m_path.clear();
70  m_isV6 = false;
71 
72  static const boost::regex protocolExp("(\\w+\\d?(\\+\\w+)?)://([^/]*)(\\/[^?]*)?");
73  boost::smatch protocolMatch;
74  if (!boost::regex_match(uri, protocolMatch, protocolExp)) {
75  return false;
76  }
77  m_scheme = protocolMatch[1];
78  const std::string& authority = protocolMatch[3];
79  m_path = protocolMatch[4];
80 
81  // pattern for IPv6 link local address enclosed in [ ], with optional port number
82  static const boost::regex v6LinkLocalExp("^\\[([a-fA-F0-9:]+)%([^\\s/:]+)\\](?:\\:(\\d+))?$");
83  // pattern for IPv6 address enclosed in [ ], with optional port number
84  static const boost::regex v6Exp("^\\[([a-fA-F0-9:]+)\\](?:\\:(\\d+))?$");
85  // pattern for Ethernet address in standard hex-digits-and-colons notation
86  static const boost::regex etherExp("^\\[((?:[a-fA-F0-9]{1,2}\\:){5}(?:[a-fA-F0-9]{1,2}))\\]$");
87  // pattern for IPv4-mapped IPv6 address, with optional port number
88  static const boost::regex v4MappedV6Exp("^\\[::ffff:(\\d+(?:\\.\\d+){3})\\](?:\\:(\\d+))?$");
89  // pattern for IPv4/hostname/fd/ifname, with optional port number
90  static const boost::regex v4HostExp("^([^:]+)(?:\\:(\\d+))?$");
91 
92  if (authority.empty()) {
93  // UNIX, internal
94  }
95  else {
96  boost::smatch match;
97  if (boost::regex_match(authority, match, v6LinkLocalExp)) {
98  m_isV6 = true;
99  m_host = match[1] + "%" + match[2];
100  m_port = match[3];
101  return true;
102  }
103 
104  m_isV6 = boost::regex_match(authority, match, v6Exp);
105  if (m_isV6 ||
106  boost::regex_match(authority, match, etherExp) ||
107  boost::regex_match(authority, match, v4MappedV6Exp) ||
108  boost::regex_match(authority, match, v4HostExp)) {
109  m_host = match[1];
110  m_port = match[2];
111  }
112  else {
113  return false;
114  }
115  }
116 
117  return true;
118 }
119 
120 FaceUri::FaceUri(const boost::asio::ip::udp::endpoint& endpoint)
121 {
122  m_isV6 = endpoint.address().is_v6();
123  m_scheme = m_isV6 ? "udp6" : "udp4";
124  m_host = endpoint.address().to_string();
125  m_port = to_string(endpoint.port());
126 }
127 
128 FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint)
129 {
130  m_isV6 = endpoint.address().is_v6();
131  m_scheme = m_isV6 ? "tcp6" : "tcp4";
132  m_host = endpoint.address().to_string();
133  m_port = to_string(endpoint.port());
134 }
135 
136 FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint, const std::string& scheme)
137 {
138  m_isV6 = endpoint.address().is_v6();
139  m_scheme = scheme;
140  m_host = endpoint.address().to_string();
141  m_port = to_string(endpoint.port());
142 }
143 
144 #ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS
145 FaceUri::FaceUri(const boost::asio::local::stream_protocol::endpoint& endpoint)
146  : m_scheme("unix")
147  , m_path(endpoint.path())
148  , m_isV6(false)
149 {
150 }
151 #endif // BOOST_ASIO_HAS_LOCAL_SOCKETS
152 
153 FaceUri
155 {
156  FaceUri uri;
157  uri.m_scheme = "fd";
158  uri.m_host = to_string(fd);
159  return uri;
160 }
161 
163  : m_scheme("ether")
164  , m_host(address.toString())
165  , m_isV6(true)
166 {
167 }
168 
169 FaceUri
170 FaceUri::fromDev(const std::string& ifname)
171 {
172  FaceUri uri;
173  uri.m_scheme = "dev";
174  uri.m_host = ifname;
175  return uri;
176 }
177 
178 FaceUri
179 FaceUri::fromUdpDev(const boost::asio::ip::udp::endpoint& endpoint, const std::string& ifname)
180 {
181  FaceUri uri;
182  uri.m_scheme = endpoint.address().is_v6() ? "udp6+dev" : "udp4+dev";
183  uri.m_host = ifname;
184  uri.m_port = to_string(endpoint.port());
185  return uri;
186 }
187 
188 bool
189 FaceUri::operator==(const FaceUri& rhs) const
190 {
191  return m_isV6 == rhs.m_isV6 &&
192  m_scheme == rhs.m_scheme &&
193  m_host == rhs.m_host &&
194  m_port == rhs.m_port &&
195  m_path == rhs.m_path;
196 }
197 
198 bool
199 FaceUri::operator!=(const FaceUri& rhs) const
200 {
201  return !(*this == rhs);
202 }
203 
204 std::string
206 {
207  std::ostringstream os;
208  os << *this;
209  return os.str();
210 }
211 
212 std::ostream&
213 operator<<(std::ostream& os, const FaceUri& uri)
214 {
215  os << uri.m_scheme << "://";
216  if (uri.m_isV6) {
217  os << "[" << uri.m_host << "]";
218  }
219  else {
220  os << uri.m_host;
221  }
222  if (!uri.m_port.empty()) {
223  os << ":" << uri.m_port;
224  }
225  os << uri.m_path;
226  return os;
227 }
228 
229 
232 class CanonizeProvider : noncopyable
233 {
234 public:
235  virtual
236  ~CanonizeProvider() = default;
237 
238  virtual std::set<std::string>
239  getSchemes() const = 0;
240 
241  virtual bool
242  isCanonical(const FaceUri& faceUri) const = 0;
243 
244  virtual void
245  canonize(const FaceUri& faceUri,
246  const FaceUri::CanonizeSuccessCallback& onSuccess,
247  const FaceUri::CanonizeFailureCallback& onFailure,
248  boost::asio::io_service& io, time::nanoseconds timeout) const = 0;
249 };
250 
251 template<typename Protocol>
253 {
254 public:
255  std::set<std::string>
256  getSchemes() const override
257  {
258  return {m_baseScheme, m_v4Scheme, m_v6Scheme};
259  }
260 
261  bool
262  isCanonical(const FaceUri& faceUri) const override
263  {
264  if (faceUri.getPort().empty()) {
265  return false;
266  }
267  if (!faceUri.getPath().empty()) {
268  return false;
269  }
270 
271  boost::system::error_code ec;
272  auto addr = ip::addressFromString(unescapeHost(faceUri.getHost()), ec);
273  if (ec) {
274  return false;
275  }
276 
277  bool hasCorrectScheme = (faceUri.getScheme() == m_v4Scheme && addr.is_v4()) ||
278  (faceUri.getScheme() == m_v6Scheme && addr.is_v6());
279  if (!hasCorrectScheme) {
280  return false;
281  }
282 
283  auto checkAddressWithUri = [] (const boost::asio::ip::address& addr,
284  const FaceUri& faceUri) -> bool {
285  if (addr.is_v4() || !addr.to_v6().is_link_local()) {
286  return addr.to_string() == faceUri.getHost();
287  }
288 
289  std::vector<std::string> addrFields, faceUriFields;
290  std::string addrString = addr.to_string();
291  std::string faceUriString = faceUri.getHost();
292 
293  boost::algorithm::split(addrFields, addrString, boost::is_any_of("%"));
294  boost::algorithm::split(faceUriFields, faceUriString, boost::is_any_of("%"));
295  if (addrFields.size() != 2 || faceUriFields.size() != 2) {
296  return false;
297  }
298 
299  if (faceUriFields[1].size() > 2 && faceUriFields[1].compare(0, 2, "25") == 0) {
300  // %25... is accepted, but not a canonical form
301  return false;
302  }
303 
304  return addrFields[0] == faceUriFields[0] &&
305  addrFields[1] == faceUriFields[1];
306  };
307 
308  return checkAddressWithUri(addr, faceUri) && checkAddress(addr).first;
309  }
310 
311  void
312  canonize(const FaceUri& faceUri,
313  const FaceUri::CanonizeSuccessCallback& onSuccess,
314  const FaceUri::CanonizeFailureCallback& onFailure,
315  boost::asio::io_service& io, time::nanoseconds timeout) const override
316  {
317  if (this->isCanonical(faceUri)) {
318  onSuccess(faceUri);
319  return;
320  }
321 
322  // make a copy because caller may modify faceUri
323  auto uri = make_shared<FaceUri>(faceUri);
324  boost::system::error_code ec;
325  auto ipAddress = ip::addressFromString(unescapeHost(faceUri.getHost()), ec);
326  if (!ec) {
327  // No need to resolve IP address if host is already an IP
328  if ((faceUri.getScheme() == m_v4Scheme && !ipAddress.is_v4()) ||
329  (faceUri.getScheme() == m_v6Scheme && !ipAddress.is_v6())) {
330  return onFailure("IPv4/v6 mismatch");
331  }
332 
333  onDnsSuccess(uri, onSuccess, onFailure, ipAddress);
334  }
335  else {
336  dns::AddressSelector addressSelector;
337  if (faceUri.getScheme() == m_v4Scheme) {
338  addressSelector = dns::Ipv4Only();
339  }
340  else if (faceUri.getScheme() == m_v6Scheme) {
341  addressSelector = dns::Ipv6Only();
342  }
343  else {
344  BOOST_ASSERT(faceUri.getScheme() == m_baseScheme);
345  addressSelector = dns::AnyAddress();
346  }
347 
348  dns::asyncResolve(unescapeHost(faceUri.getHost()),
349  bind(&IpHostCanonizeProvider<Protocol>::onDnsSuccess, this, uri, onSuccess, onFailure, _1),
350  bind(&IpHostCanonizeProvider<Protocol>::onDnsFailure, this, uri, onFailure, _1),
351  io, addressSelector, timeout);
352  }
353  }
354 
355 protected:
356  explicit
357  IpHostCanonizeProvider(const std::string& baseScheme,
358  uint16_t defaultUnicastPort = 6363,
359  uint16_t defaultMulticastPort = 56363)
360  : m_baseScheme(baseScheme)
361  , m_v4Scheme(baseScheme + '4')
362  , m_v6Scheme(baseScheme + '6')
363  , m_defaultUnicastPort(defaultUnicastPort)
364  , m_defaultMulticastPort(defaultMulticastPort)
365  {
366  }
367 
368 private:
369  void
370  onDnsSuccess(const shared_ptr<FaceUri>& faceUri,
371  const FaceUri::CanonizeSuccessCallback& onSuccess,
372  const FaceUri::CanonizeFailureCallback& onFailure,
373  const dns::IpAddress& ipAddress) const
374  {
375  bool isOk = false;
376  std::string reason;
377  std::tie(isOk, reason) = this->checkAddress(ipAddress);
378  if (!isOk) {
379  return onFailure(reason);
380  }
381 
382  uint16_t port = 0;
383  if (faceUri->getPort().empty()) {
384  port = ipAddress.is_multicast() ? m_defaultMulticastPort : m_defaultUnicastPort;
385  }
386  else {
387  try {
388  port = boost::lexical_cast<uint16_t>(faceUri->getPort());
389  }
390  catch (const boost::bad_lexical_cast&) {
391  return onFailure("invalid port number '" + faceUri->getPort() + "'");
392  }
393  }
394 
395  FaceUri canonicalUri(typename Protocol::endpoint(ipAddress, port));
396  BOOST_ASSERT(canonicalUri.isCanonical());
397  onSuccess(canonicalUri);
398  }
399 
400  void
401  onDnsFailure(const shared_ptr<FaceUri>& faceUri,
402  const FaceUri::CanonizeFailureCallback& onFailure,
403  const std::string& reason) const
404  {
405  onFailure(reason);
406  }
407 
412  virtual std::pair<bool, std::string>
413  checkAddress(const dns::IpAddress& ipAddress) const
414  {
415  return {true, ""};
416  }
417 
418  static std::string
419  unescapeHost(std::string host)
420  {
421  auto escapePos = host.find("%25");
422  if (escapePos != std::string::npos && escapePos < host.size() - 3) {
423  host = unescape(host);
424  }
425  return host;
426  }
427 
428 private:
429  std::string m_baseScheme;
430  std::string m_v4Scheme;
431  std::string m_v6Scheme;
432  uint16_t m_defaultUnicastPort;
433  uint16_t m_defaultMulticastPort;
434 };
435 
436 class UdpCanonizeProvider : public IpHostCanonizeProvider<boost::asio::ip::udp>
437 {
438 public:
440  : IpHostCanonizeProvider("udp")
441  {
442  }
443 };
444 
445 class TcpCanonizeProvider : public IpHostCanonizeProvider<boost::asio::ip::tcp>
446 {
447 public:
449  : IpHostCanonizeProvider("tcp")
450  {
451  }
452 
453 protected:
454  std::pair<bool, std::string>
455  checkAddress(const dns::IpAddress& ipAddress) const override
456  {
457  if (ipAddress.is_multicast()) {
458  return {false, "cannot use multicast address"};
459  }
460  return {true, ""};
461  }
462 };
463 
465 {
466 public:
467  std::set<std::string>
468  getSchemes() const override
469  {
470  return {"ether"};
471  }
472 
473  bool
474  isCanonical(const FaceUri& faceUri) const override
475  {
476  if (!faceUri.getPort().empty()) {
477  return false;
478  }
479  if (!faceUri.getPath().empty()) {
480  return false;
481  }
482 
483  auto addr = ethernet::Address::fromString(faceUri.getHost());
484  return addr.toString() == faceUri.getHost();
485  }
486 
487  void
488  canonize(const FaceUri& faceUri,
489  const FaceUri::CanonizeSuccessCallback& onSuccess,
490  const FaceUri::CanonizeFailureCallback& onFailure,
491  boost::asio::io_service& io, time::nanoseconds timeout) const override
492  {
493  auto addr = ethernet::Address::fromString(faceUri.getHost());
494  if (addr.isNull()) {
495  return onFailure("invalid ethernet address '" + faceUri.getHost() + "'");
496  }
497 
498  FaceUri canonicalUri(addr);
499  BOOST_ASSERT(canonicalUri.isCanonical());
500  onSuccess(canonicalUri);
501  }
502 };
503 
505 {
506 public:
507  std::set<std::string>
508  getSchemes() const override
509  {
510  return {"dev"};
511  }
512 
513  bool
514  isCanonical(const FaceUri& faceUri) const override
515  {
516  return !faceUri.getHost().empty() && faceUri.getPort().empty() && faceUri.getPath().empty();
517  }
518 
519  void
520  canonize(const FaceUri& faceUri,
521  const FaceUri::CanonizeSuccessCallback& onSuccess,
522  const FaceUri::CanonizeFailureCallback& onFailure,
523  boost::asio::io_service& io, time::nanoseconds timeout) const override
524  {
525  if (faceUri.getHost().empty()) {
526  onFailure("network interface name is missing");
527  return;
528  }
529  if (!faceUri.getPort().empty()) {
530  onFailure("port number is not allowed");
531  return;
532  }
533  if (!faceUri.getPath().empty() && faceUri.getPath() != "/") { // permit trailing slash only
534  onFailure("path is not allowed");
535  return;
536  }
537 
538  FaceUri canonicalUri = FaceUri::fromDev(faceUri.getHost());
539  BOOST_ASSERT(canonicalUri.isCanonical());
540  onSuccess(canonicalUri);
541  }
542 };
543 
545 {
546 public:
547  std::set<std::string>
548  getSchemes() const override
549  {
550  return {"udp4+dev", "udp6+dev"};
551  }
552 
553  bool
554  isCanonical(const FaceUri& faceUri) const override
555  {
556  if (faceUri.getPort().empty()) {
557  return false;
558  }
559  if (!faceUri.getPath().empty()) {
560  return false;
561  }
562  return true;
563  }
564 
565  void
566  canonize(const FaceUri& faceUri,
567  const FaceUri::CanonizeSuccessCallback& onSuccess,
568  const FaceUri::CanonizeFailureCallback& onFailure,
569  boost::asio::io_service& io, time::nanoseconds timeout) const override
570  {
571  if (this->isCanonical(faceUri)) {
572  onSuccess(faceUri);
573  }
574  else {
575  onFailure("cannot canonize " + faceUri.toString());
576  }
577  }
578 };
579 
580 using CanonizeProviders = boost::mpl::vector<UdpCanonizeProvider*,
581  TcpCanonizeProvider*,
582  EtherCanonizeProvider*,
583  DevCanonizeProvider*,
585 using CanonizeProviderTable = std::map<std::string, shared_ptr<CanonizeProvider>>;
586 
588 {
589 public:
590  explicit
592  : m_providerTable(providerTable)
593  {
594  }
595 
596  template<typename CP>
597  void
599  {
600  shared_ptr<CanonizeProvider> cp = make_shared<CP>();
601  auto schemes = cp->getSchemes();
602  BOOST_ASSERT(!schemes.empty());
603 
604  for (const auto& scheme : schemes) {
605  BOOST_ASSERT(m_providerTable.count(scheme) == 0);
606  m_providerTable[scheme] = cp;
607  }
608  }
609 
610 private:
611  CanonizeProviderTable& m_providerTable;
612 };
613 
614 static const CanonizeProvider*
615 getCanonizeProvider(const std::string& scheme)
616 {
617  static CanonizeProviderTable providerTable;
618  if (providerTable.empty()) {
619  boost::mpl::for_each<CanonizeProviders>(CanonizeProviderTableInitializer(providerTable));
620  BOOST_ASSERT(!providerTable.empty());
621  }
622 
623  auto it = providerTable.find(scheme);
624  return it == providerTable.end() ? nullptr : it->second.get();
625 }
626 
627 
628 bool
629 FaceUri::canCanonize(const std::string& scheme)
630 {
631  return getCanonizeProvider(scheme) != nullptr;
632 }
633 
634 bool
636 {
637  const CanonizeProvider* cp = getCanonizeProvider(this->getScheme());
638  if (cp == nullptr) {
639  return false;
640  }
641 
642  return cp->isCanonical(*this);
643 }
644 
645 void
647  const CanonizeFailureCallback& onFailure,
648  boost::asio::io_service& io, time::nanoseconds timeout) const
649 {
650  const CanonizeProvider* cp = getCanonizeProvider(this->getScheme());
651  if (cp == nullptr) {
652  if (onFailure) {
653  onFailure("scheme not supported");
654  }
655  return;
656  }
657 
658  static CanonizeSuccessCallback successNop = bind([]{});
659  static CanonizeFailureCallback failureNop = bind([]{});
660  cp->canonize(*this,
661  onSuccess ? onSuccess : successNop,
662  onFailure ? onFailure : failureNop,
663  io, timeout);
664 }
665 
666 } // namespace ndn
IpHostCanonizeProvider(const std::string &baseScheme, uint16_t defaultUnicastPort=6363, uint16_t defaultMulticastPort=56363)
Definition: face-uri.cpp:357
std::set< std::string > getSchemes() const override
Definition: face-uri.cpp:508
virtual ~CanonizeProvider()=default
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.
Definition: ethernet.cpp:92
Copyright (c) 2011-2015 Regents of the University of California.
function< void(const std::string &reason)> CanonizeFailureCallback
Definition: face-uri.hpp:165
static FaceUri fromFd(int fd)
create fd FaceUri from file descriptor
Definition: face-uri.cpp:154
bool isCanonical(const FaceUri &faceUri) const override
Definition: face-uri.cpp:554
const std::string & getHost() const
get host (domain)
Definition: face-uri.hpp:120
bool isCanonical(const FaceUri &faceUri) const override
Definition: face-uri.cpp:474
bool operator!=(const FaceUri &rhs) const
Definition: face-uri.cpp:199
void canonize(const FaceUri &faceUri, const FaceUri::CanonizeSuccessCallback &onSuccess, const FaceUri::CanonizeFailureCallback &onFailure, boost::asio::io_service &io, time::nanoseconds timeout) const override
Definition: face-uri.cpp:566
function< void(const FaceUri &)> CanonizeSuccessCallback
Definition: face-uri.hpp:164
std::ostream & operator<<(std::ostream &os, const Data &data)
Definition: data.cpp:274
static bool canCanonize(const std::string &scheme)
Definition: face-uri.cpp:629
std::string toString() const
write as a string
Definition: face-uri.cpp:205
virtual bool isCanonical(const FaceUri &faceUri) const =0
bool isCanonical(const FaceUri &faceUri) const override
Definition: face-uri.cpp:262
static const CanonizeProvider * getCanonizeProvider(const std::string &scheme)
Definition: face-uri.cpp:615
const std::string & getPort() const
get port
Definition: face-uri.hpp:127
STL namespace.
std::string toString(char sep=':') const
Converts the address to a human-readable string.
Definition: ethernet.cpp:78
function< bool(const IpAddress &address)> AddressSelector
Definition: dns.hpp:34
bool isCanonical(const FaceUri &faceUri) const override
Definition: face-uri.cpp:514
std::set< std::string > getSchemes() const override
Definition: face-uri.cpp:548
static FaceUri fromUdpDev(const boost::asio::ip::udp::endpoint &endpoint, const std::string &ifname)
create udp4 or udp6 NIC-associated FaceUri from endpoint and network device name
Definition: face-uri.cpp:179
std::string toString(const system_clock::TimePoint &timePoint, const std::string &format, const std::locale &locale)
Convert time point to string with specified format.
Definition: time.cpp:170
a CanonizeProvider provides FaceUri canonization functionality for a group of schemes ...
Definition: face-uri.cpp:232
bool parse(const std::string &uri)
exception-safe parsing
Definition: face-uri.cpp:64
void canonize(const FaceUri &faceUri, const FaceUri::CanonizeSuccessCallback &onSuccess, const FaceUri::CanonizeFailureCallback &onFailure, boost::asio::io_service &io, time::nanoseconds timeout) const override
Definition: face-uri.cpp:520
std::pair< bool, std::string > checkAddress(const dns::IpAddress &ipAddress) const override
when overriden in a subclass, check the IP address is allowable
Definition: face-uri.cpp:455
std::string unescape(const std::string &str)
Decode a percent-encoded string.
std::set< std::string > getSchemes() const override
Definition: face-uri.cpp:468
void canonize(const CanonizeSuccessCallback &onSuccess, const CanonizeFailureCallback &onFailure, boost::asio::io_service &io, time::nanoseconds timeout) const
asynchronously convert this FaceUri to canonical form
Definition: face-uri.cpp:646
represents the underlying protocol and address used by a Face
Definition: face-uri.hpp:44
boost::asio::ip::address addressFromString(const std::string &address, boost::system::error_code &ec)
parse and convert the input string into an IP address
represents an Ethernet hardware address
Definition: ethernet.hpp:52
const std::string & getScheme() const
get scheme (protocol)
Definition: face-uri.hpp:113
boost::asio::ip::address IpAddress
Definition: dns.hpp:33
CanonizeProviderTableInitializer(CanonizeProviderTable &providerTable)
Definition: face-uri.cpp:591
bool operator==(const FaceUri &rhs) const
Definition: face-uri.cpp:189
std::set< std::string > getSchemes() const override
Definition: face-uri.cpp:256
std::string to_string(const V &v)
Definition: backports.hpp:84
void canonize(const FaceUri &faceUri, const FaceUri::CanonizeSuccessCallback &onSuccess, const FaceUri::CanonizeFailureCallback &onFailure, boost::asio::io_service &io, time::nanoseconds timeout) const override
Definition: face-uri.cpp:312
bool isCanonical() const
determine whether this FaceUri is in canonical form
Definition: face-uri.cpp:635
std::map< std::string, shared_ptr< CanonizeProvider > > CanonizeProviderTable
Definition: face-uri.cpp:585
virtual void canonize(const FaceUri &faceUri, const FaceUri::CanonizeSuccessCallback &onSuccess, const FaceUri::CanonizeFailureCallback &onFailure, boost::asio::io_service &io, time::nanoseconds timeout) const =0
const std::string & getPath() const
get path
Definition: face-uri.hpp:134
boost::mpl::vector< UdpCanonizeProvider *, TcpCanonizeProvider *, EtherCanonizeProvider *, DevCanonizeProvider *, UdpDevCanonizeProvider * > CanonizeProviders
Definition: face-uri.cpp:584
void asyncResolve(const std::string &host, const SuccessCallback &onSuccess, const ErrorCallback &onError, boost::asio::io_service &ioService, const AddressSelector &addressSelector, time::nanoseconds timeout)
Asynchronously resolve host.
Definition: dns.cpp:132
static FaceUri fromDev(const std::string &ifname)
create dev FaceUri from network device name
Definition: face-uri.cpp:170
void canonize(const FaceUri &faceUri, const FaceUri::CanonizeSuccessCallback &onSuccess, const FaceUri::CanonizeFailureCallback &onFailure, boost::asio::io_service &io, time::nanoseconds timeout) const override
Definition: face-uri.cpp:488
virtual std::set< std::string > getSchemes() const =0