util: FaceUri: add syntax for NIC-associated permanent faces
refs #3522
Change-Id: Id2c9f751d7d1f65b2f0ef968aad660e95250d155
diff --git a/src/util/face-uri.cpp b/src/util/face-uri.cpp
index 4ad9dba..acdbc11 100644
--- a/src/util/face-uri.cpp
+++ b/src/util/face-uri.cpp
@@ -68,14 +68,14 @@
m_port.clear();
m_path.clear();
- static const boost::regex protocolExp("(\\w+\\d?)://([^/]*)(\\/[^?]*)?");
+ static const boost::regex protocolExp("(\\w+\\d?(\\+\\w+)?)://([^/]*)(\\/[^?]*)?");
boost::smatch protocolMatch;
if (!boost::regex_match(uri, protocolMatch, protocolExp)) {
return false;
}
m_scheme = protocolMatch[1];
- const std::string& authority = protocolMatch[2];
- m_path = protocolMatch[3];
+ const std::string& authority = protocolMatch[3];
+ m_path = protocolMatch[4];
// pattern for IPv6 address enclosed in [ ], with optional port number
static const boost::regex v6Exp("^\\[([a-fA-F0-9:]+)\\](?:\\:(\\d+))?$");
@@ -112,7 +112,7 @@
m_isV6 = endpoint.address().is_v6();
m_scheme = m_isV6 ? "udp6" : "udp4";
m_host = endpoint.address().to_string();
- m_port = boost::lexical_cast<std::string>(endpoint.port());
+ m_port = to_string(endpoint.port());
}
FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint)
@@ -120,7 +120,7 @@
m_isV6 = endpoint.address().is_v6();
m_scheme = m_isV6 ? "tcp6" : "tcp4";
m_host = endpoint.address().to_string();
- m_port = boost::lexical_cast<std::string>(endpoint.port());
+ m_port = to_string(endpoint.port());
}
FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint, const std::string& scheme)
@@ -128,7 +128,7 @@
{
m_isV6 = endpoint.address().is_v6();
m_host = endpoint.address().to_string();
- m_port = boost::lexical_cast<std::string>(endpoint.port());
+ m_port = to_string(endpoint.port());
}
#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS
@@ -145,7 +145,7 @@
{
FaceUri uri;
uri.m_scheme = "fd";
- uri.m_host = boost::lexical_cast<std::string>(fd);
+ uri.m_host = to_string(fd);
return uri;
}
@@ -165,6 +165,16 @@
return uri;
}
+FaceUri
+FaceUri::fromUdpDev(const boost::asio::ip::udp::endpoint& endpoint, const std::string& ifname)
+{
+ FaceUri uri;
+ uri.m_scheme = endpoint.address().is_v6() ? "udp6+dev" : "udp4+dev";
+ uri.m_host = ifname;
+ uri.m_port = to_string(endpoint.port());
+ return uri;
+}
+
bool
FaceUri::operator==(const FaceUri& rhs) const
{
@@ -445,10 +455,47 @@
}
};
+class UdpDevCanonizeProvider : public CanonizeProvider
+{
+public:
+ virtual std::set<std::string>
+ getSchemes() const override
+ {
+ return {"udp4+dev", "udp6+dev"};
+ }
+
+ virtual bool
+ isCanonical(const FaceUri& faceUri) const override
+ {
+ if (faceUri.getPort().empty()) {
+ return false;
+ }
+ if (!faceUri.getPath().empty()) {
+ return false;
+ }
+ return true;
+ }
+
+ virtual void
+ canonize(const FaceUri& faceUri,
+ const FaceUri::CanonizeSuccessCallback& onSuccess,
+ const FaceUri::CanonizeFailureCallback& onFailure,
+ boost::asio::io_service& io, const time::nanoseconds& timeout) const override
+ {
+ if (this->isCanonical(faceUri)) {
+ onSuccess(faceUri);
+ }
+ else {
+ onFailure("cannot canonize " + faceUri.toString());
+ }
+ }
+};
+
typedef boost::mpl::vector<
UdpCanonizeProvider*,
TcpCanonizeProvider*,
- EtherCanonizeProvider*
+ EtherCanonizeProvider*,
+ UdpDevCanonizeProvider*
> CanonizeProviders;
typedef std::map<std::string, shared_ptr<CanonizeProvider> > CanonizeProviderTable;
diff --git a/src/util/face-uri.hpp b/src/util/face-uri.hpp
index f7cbe41..b222323 100644
--- a/src/util/face-uri.hpp
+++ b/src/util/face-uri.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -103,6 +103,10 @@
static FaceUri
fromDev(const std::string& ifname);
+ /// create udp4 or udp6 NIC-associated FaceUri from endpoint and network device name
+ static FaceUri
+ fromUdpDev(const boost::asio::ip::udp::endpoint& endpoint, const std::string& ifname);
+
public: // getters
/// get scheme (protocol)
const std::string&