[asterisk-scf-commits] asterisk-scf/release/ice-util-cpp.git branch "master" updated.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Wed Jul 20 13:07:27 CDT 2011
branch "master" has been updated
via f18ca9c161f989c7a2f8423c0b4b17b7ea594bac (commit)
from 81d6eb6688d12416f6761ac9eef9d488f5001622 (commit)
Summary of changes:
include/AsteriskSCF/Helpers/Network.h | 98 ++++++++++++
.../AsteriskSCF/NAT/Candidates.h | 23 ++--
src/CMakeLists.txt | 4 +-
src/Helpers/CMakeLists.txt | 1 +
src/Helpers/Network.cpp | 135 +++++++++++++++++
src/NAT/CMakeLists.txt | 1 +
src/NAT/Candidates.cpp | 160 ++++++++++++++++++++
7 files changed, 409 insertions(+), 13 deletions(-)
create mode 100644 include/AsteriskSCF/Helpers/Network.h
copy test/PropertyHelper/PropertyHelperTest.h => include/AsteriskSCF/NAT/Candidates.h (61%)
create mode 100644 src/Helpers/CMakeLists.txt
create mode 100644 src/Helpers/Network.cpp
create mode 100644 src/NAT/CMakeLists.txt
create mode 100644 src/NAT/Candidates.cpp
- Log -----------------------------------------------------------------
commit f18ca9c161f989c7a2f8423c0b4b17b7ea594bac
Author: Brent Eagles <beagles at digium.com>
Date: Wed Jul 20 15:35:33 2011 -0230
- Added helper classes for dealing with network addresses. These employ the
relevant boost libraries and provide rudimentary hostname->IP address
resolution.
- Added a simple helper free function for converting an Ice Candidate object
to an ICE SDP attribute.
diff --git a/include/AsteriskSCF/Helpers/Network.h b/include/AsteriskSCF/Helpers/Network.h
new file mode 100644
index 0000000..23a0f3c
--- /dev/null
+++ b/include/AsteriskSCF/Helpers/Network.h
@@ -0,0 +1,98 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+#include <boost/thread.hpp>
+
+#ifdef _WIN32
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+
+namespace AsteriskSCF
+{
+namespace Helpers
+{
+
+//
+// NOTE: I discovered that boost asio covers this territory, only with greater detail. I decided to keep going as I was
+// planning something far more basic to use. It's implemented in terms of asio though.
+//
+class ASTSCF_DLL_EXPORT Address
+{
+ //
+ // We don't want a proper assignment operator, this is to behave more like
+ // an atomic type and the only way to really do that is to hide the members
+ // and only allow modification through construction.
+ //
+ void operator=(const Address&);
+public:
+
+ Address(const std::string& hostname, unsigned port);
+ Address(const Address&);
+
+ unsigned port() const;
+ std::string hostname() const;
+ std::string address() const;
+
+ bool isIPV6();
+
+ std::string toString() const;
+
+private:
+ std::string mHostname;
+ std::string mAddress;
+ unsigned mPort;
+
+ bool mIsIPV6;
+};
+typedef boost::shared_ptr<Address> AddressPtr;
+typedef std::vector<AddressPtr> AddressSeq;
+
+/**
+ *
+ **/
+class ASTSCF_DLL_EXPORT DNSQuery
+{
+public:
+ virtual ~DNSQuery();
+ static boost::shared_ptr<DNSQuery> create(const std::string& hostname, const std::string& serviceName);
+ static boost::shared_ptr<DNSQuery> create(const std::string& hostname, const int portNumber);
+
+ virtual AddressSeq execute() = 0;
+
+protected:
+ DNSQuery();
+
+private:
+ //
+ // Not implemented.
+ //
+ DNSQuery(const DNSQuery&);
+ void operator=(const DNSQuery&);
+};
+typedef boost::shared_ptr<DNSQuery> DNSQueryPtr;
+
+
+} /* End of namespace Helpers */
+} /* End of namespace AsteriskSCF */
+
+#ifdef _WIN32
+#pragma warning(pop)
+#endif
diff --git a/include/AsteriskSCF/NAT/Candidates.h b/include/AsteriskSCF/NAT/Candidates.h
new file mode 100644
index 0000000..1aa024e
--- /dev/null
+++ b/include/AsteriskSCF/NAT/Candidates.h
@@ -0,0 +1,35 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include <string>
+#include <AsteriskSCF/System/NAT/NATTraversalIf.h>
+
+namespace AsteriskSCF
+{
+namespace NAT
+{
+
+/**
+ *
+ * toSDP() creates an SDP compliant attribute line for the provided candidate.
+ *
+ **/
+std::string ASTSCF_DLL_EXPORT toSDP(const AsteriskSCF::System::NAT::V1::CandidatePtr& candidate);
+
+} /* End of namespace NAT */
+} /* End of namespace AsteriskSCF */
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 082821e..d0a9c90 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -4,8 +4,10 @@ astscf_component_add_files(astscf-ice-util-cpp ${project_headers})
add_subdirectory(CollocatedIceStorm)
add_subdirectory(WorkQueue)
add_subdirectory(ThreadPool)
+add_subdirectory(Helpers)
+add_subdirectory(NAT)
astscf_component_add_ice_libraries(astscf-ice-util-cpp IceStorm IceBox)
-astscf_component_add_boost_libraries(astscf-ice-util-cpp core thread date_time)
+astscf_component_add_boost_libraries(astscf-ice-util-cpp core thread date_time system)
astscf_component_add_slice_collection_libraries(astscf-ice-util-cpp ASTSCF)
astscf_component_build_library(astscf-ice-util-cpp)
target_link_libraries(astscf-ice-util-cpp logging-client)
diff --git a/src/Helpers/CMakeLists.txt b/src/Helpers/CMakeLists.txt
new file mode 100644
index 0000000..1c4069e
--- /dev/null
+++ b/src/Helpers/CMakeLists.txt
@@ -0,0 +1 @@
+astscf_component_add_files(astscf-ice-util-cpp Network.cpp)
diff --git a/src/Helpers/Network.cpp b/src/Helpers/Network.cpp
new file mode 100644
index 0000000..d596c52
--- /dev/null
+++ b/src/Helpers/Network.cpp
@@ -0,0 +1,135 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include <AsteriskSCF/Helpers/Network.h>
+#include <boost/asio.hpp>
+#include <boost/lexical_cast.hpp>
+#include <sstream>
+#include <iostream>
+
+using namespace std;
+using namespace AsteriskSCF::Helpers;
+using namespace boost::asio::ip;
+
+Address::Address(const string& host, unsigned p) :
+ mHostname(host),
+ mPort(p),
+ mIsIPV6(false)
+{
+ try
+ {
+ boost::asio::ip::address a(address::from_string(mHostname));
+ mAddress = mHostname;
+ mIsIPV6 = a.is_v6();
+ }
+ catch (const exception&)
+ {
+ DNSQueryPtr q = DNSQuery::create(mHostname, 0);
+ AddressSeq results = q->execute();
+ if (!results.empty())
+ {
+ mIsIPV6 = results[0]->isIPV6();
+ mAddress = results[0]->address();
+ }
+ }
+}
+
+unsigned Address::port() const
+{
+ return mPort;
+}
+
+string Address::hostname() const
+{
+ return mHostname;
+}
+
+string Address::address() const
+{
+ return mAddress;
+}
+
+bool Address::isIPV6()
+{
+ return mIsIPV6;
+}
+
+string Address::toString() const
+{
+ stringstream os;
+ if (mHostname == mAddress)
+ {
+ os << mHostname << ':' << mPort;
+ }
+ else
+ {
+ os << mHostname << '/' << mAddress << ':' << mPort;
+ }
+ return os.str();
+}
+
+class DNSQueryImpl : public DNSQuery
+{
+public:
+ explicit DNSQueryImpl(const tcp::resolver::query& query) :
+ mQuery(query),
+ mResolver(mIO)
+ {
+ }
+
+ AddressSeq execute()
+ {
+ //
+ // TODO: this can also be made to run asynchronously.
+ //
+ AddressSeq result;
+ for (tcp::resolver::iterator server = mResolver.resolve(mQuery);
+ server != tcp::resolver::iterator(); ++server)
+ {
+ tcp::endpoint ep = *server;
+ result.push_back(AddressPtr(new Address(ep.address().to_string(), ep.port())));
+ }
+ return result;
+ }
+
+private:
+ tcp::resolver::query mQuery;
+ boost::asio::io_service mIO;
+ tcp::resolver mResolver;
+};
+
+DNSQuery::~DNSQuery()
+{
+ //
+ // No-op.
+ //
+}
+
+DNSQueryPtr DNSQuery::create(const string& hostname, const string& serviceName)
+{
+ tcp::resolver::query q(hostname, serviceName);
+ return DNSQueryPtr(new DNSQueryImpl(q));
+}
+
+DNSQueryPtr DNSQuery::create(const string& hostname, const int portnumber)
+{
+ tcp::resolver::query q(hostname, boost::lexical_cast<string>(portnumber));
+ return DNSQueryPtr(new DNSQueryImpl(q));
+}
+
+DNSQuery::DNSQuery()
+{
+}
diff --git a/src/NAT/CMakeLists.txt b/src/NAT/CMakeLists.txt
new file mode 100644
index 0000000..b90886b
--- /dev/null
+++ b/src/NAT/CMakeLists.txt
@@ -0,0 +1 @@
+astscf_component_add_files(astscf-ice-util-cpp Candidates.cpp)
diff --git a/src/NAT/Candidates.cpp b/src/NAT/Candidates.cpp
new file mode 100644
index 0000000..06600e7
--- /dev/null
+++ b/src/NAT/Candidates.cpp
@@ -0,0 +1,160 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include <boost/asio/ip/address.hpp>
+#include <AsteriskSCF/NAT/Candidates.h>
+#include <AsteriskSCF/Helpers/Network.h>
+#include <sstream>
+#include <boost/functional/hash.hpp>
+
+using namespace AsteriskSCF::System::NAT::V1;
+using namespace AsteriskSCF::NAT;
+using namespace std;
+
+std::string toSDP(const AsteriskSCF::System::NAT::V1::CandidatePtr& candidate)
+{
+ stringstream os;
+ if (!candidate)
+ {
+ return "";
+ }
+
+ os << "candidate:";
+ if (candidate->foundation.empty())
+ {
+ //
+ // Foundation prefix.
+ //
+ switch (candidate->type)
+ {
+ case Host:
+ os << 'H';
+ break;
+
+ case ServerReflexive:
+ os << 'S';
+ break;
+
+ case PeerReflexive:
+ os << 'P';
+ break;
+
+ case Relayed:
+ os << 'R';
+ break;
+
+ default:
+ assert("Unknown candidate type encountered." == 0);
+ }
+ //
+ // Calculate foundation.
+ //
+ string address;
+ unsigned port;
+ if (candidate->mappedAddress.empty())
+ {
+ //
+ // If we do not have a mapped address and the candidate type is not host, then
+ // something is wrong!
+ //
+ assert (candidate->type == Host);
+ address = candidate->baseAddress;
+ port = candidate->basePort;
+ }
+ else
+ {
+ address = candidate->mappedAddress;
+ port = candidate->mappedPort;
+ }
+ AsteriskSCF::Helpers::AddressPtr addr(new AsteriskSCF::Helpers::Address(address, port));
+ //
+ // Now we can be sure we have a numeric ip address.. it would definitely fail in other ways
+ // before we got this far.
+ //
+ string ipaddr = addr->address();
+ if (addr->isIPV6())
+ {
+ boost::asio::ip::address_v6 ip = boost::asio::ip::address_v6::from_string(ipaddr);
+ boost::asio::ip::address_v6::bytes_type ipbytes = ip.to_bytes();
+ size_t seedVal = 0;
+ for (size_t i = 0; i < (sizeof(ipbytes) / sizeof(ipbytes[0])); ++i)
+ {
+ boost::hash_combine(seedVal, ipbytes[i]);
+ }
+ os << seedVal;
+ }
+ else
+ {
+ boost::asio::ip::address_v4 ip = boost::asio::ip::address_v4::from_string(ipaddr);
+ os << ip.to_ulong();
+ }
+ }
+ else
+ {
+ os << candidate->foundation;
+ }
+ os << ' ';
+ os << candidate->componentId;
+ os << ' ';
+ switch (candidate->transport)
+ {
+ case UDP:
+ os << "UDP";
+ break;
+ case TCP:
+ os << "TCP";
+ break;
+ default:
+ assert("Invalid transport value" == 0);
+ }
+
+ //
+ // If the candidate is a host candidate then we are almost done.
+ //
+ if (candidate->type == Host)
+ {
+ os << candidate->baseAddress << ' ' << candidate->basePort << " typ host";
+ return os.str();
+ }
+ //
+ // Otherwise, we've got a bit more to do.
+ //
+ os << candidate->mappedAddress << ' ' << candidate->mappedPort << "typ ";
+ switch (candidate->type)
+ {
+ case Host:
+ assert("This value isn't valid here" == 0);
+ break;
+
+ case ServerReflexive:
+ os << "srflx ";
+ break;
+
+ case PeerReflexive:
+ os << "prflx ";
+ break;
+
+ case Relayed:
+ os << "relay ";
+ break;
+
+ default:
+ assert("Unknown candidate type encountered." == 0);
+ }
+
+ os << "raddr " << candidate->baseAddress << " rport " << candidate->basePort;
+ return os.str();
+}
-----------------------------------------------------------------------
--
asterisk-scf/release/ice-util-cpp.git
More information about the asterisk-scf-commits
mailing list