diff options
Diffstat (limited to 'indra/llmessage')
-rwxr-xr-x | indra/llmessage/CMakeLists.txt | 4 | ||||
-rwxr-xr-x | indra/llmessage/llares.cpp | 839 | ||||
-rwxr-xr-x | indra/llmessage/llares.h | 583 | ||||
-rwxr-xr-x | indra/llmessage/llareslistener.cpp | 104 | ||||
-rwxr-xr-x | indra/llmessage/llareslistener.h | 53 |
5 files changed, 0 insertions, 1583 deletions
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 3bcee13d28..5877c4a8e4 100755 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -28,8 +28,6 @@ include_directories( ) set(llmessage_SOURCE_FILES - llares.cpp - llareslistener.cpp llassetstorage.cpp llavatarname.cpp llavatarnamecache.cpp @@ -109,8 +107,6 @@ set(llmessage_SOURCE_FILES set(llmessage_HEADER_FILES CMakeLists.txt - llares.h - llareslistener.h llassetstorage.h llavatarname.h llavatarnamecache.h diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp deleted file mode 100755 index 9f90ae1544..0000000000 --- a/indra/llmessage/llares.cpp +++ /dev/null @@ -1,839 +0,0 @@ -/** - * @file llares.cpp - * @author Bryan O'Sullivan - * @date 2007-08-15 - * @brief Wrapper for asynchronous DNS lookups. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "llares.h" - -#include <ares_dns.h> -#include <ares_version.h> - -#include "apr_portable.h" -#include "apr_network_io.h" -#include "apr_poll.h" - -#include "llapr.h" -#include "llareslistener.h" - -#if defined(LL_WINDOWS) -#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally -# define ns_c_in 1 -# define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */ -# define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */ -# define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ -#else -# include <arpa/nameser.h> -#endif - -LLAres::HostResponder::~HostResponder() -{ -} - -void LLAres::HostResponder::hostResult(const hostent *ent) -{ - LL_INFOS() << "LLAres::HostResponder::hostResult not implemented" << LL_ENDL; -} - -void LLAres::HostResponder::hostError(int code) -{ - LL_INFOS() << "LLAres::HostResponder::hostError " << code << ": " - << LLAres::strerror(code) << LL_ENDL; -} - -LLAres::NameInfoResponder::~NameInfoResponder() -{ -} - -void LLAres::NameInfoResponder::nameInfoResult(const char *node, - const char *service) -{ - LL_INFOS() << "LLAres::NameInfoResponder::nameInfoResult not implemented" - << LL_ENDL; -} - -void LLAres::NameInfoResponder::nameInfoError(int code) -{ - LL_INFOS() << "LLAres::NameInfoResponder::nameInfoError " << code << ": " - << LLAres::strerror(code) << LL_ENDL; -} - -LLAres::QueryResponder::~QueryResponder() -{ -} - -void LLAres::QueryResponder::queryResult(const char *buf, size_t len) -{ - LL_INFOS() << "LLAres::QueryResponder::queryResult not implemented" - << LL_ENDL; -} - -void LLAres::QueryResponder::queryError(int code) -{ - LL_INFOS() << "LLAres::QueryResponder::queryError " << code << ": " - << LLAres::strerror(code) << LL_ENDL; -} - -LLAres::LLAres() : - chan_(NULL), - mInitSuccess(false) -{ - if (ares_library_init( ARES_LIB_INIT_ALL ) != ARES_SUCCESS || - ares_init(&chan_) != ARES_SUCCESS) - { - LL_WARNS() << "Could not succesfully initialize ares!" << LL_ENDL; - return; - } - - mListener = boost::shared_ptr< LLAresListener >(new LLAresListener(this)); - - mInitSuccess = true; -} - -LLAres::~LLAres() -{ - ares_destroy(chan_); - ares_library_cleanup(); -} - -void LLAres::cancel() -{ - ares_cancel(chan_); -} - -static void host_callback_1_5(void *arg, int status, int timeouts, - struct hostent *ent) -{ - LLPointer<LLAres::HostResponder> *resp = - (LLPointer<LLAres::HostResponder> *) arg; - - if (status == ARES_SUCCESS) - { - (*resp)->hostResult(ent); - } else { - (*resp)->hostError(status); - } - - delete resp; -} - -#if ARES_VERSION_MAJOR == 1 && ARES_VERSION_MINOR == 4 -static void host_callback(void *arg, int status, struct hostent *ent) -{ - host_callback_1_5(arg, status, 0, ent); -} -#else -# define host_callback host_callback_1_5 -#endif - -void LLAres::getHostByName(const char *name, HostResponder *resp, - int family) -{ - ares_gethostbyname(chan_, name, family, host_callback, - new LLPointer<LLAres::HostResponder>(resp)); -} - -void LLAres::getSrvRecords(const std::string &name, SrvResponder *resp) -{ - search(name, RES_SRV, resp); -} - -void LLAres::rewriteURI(const std::string &uri, UriRewriteResponder *resp) -{ - if (resp && uri.size()) - { - LLURI* pURI = new LLURI(uri); - - resp->mUri = *pURI; - - delete pURI; - - if (!resp->mUri.scheme().size() || !resp->mUri.hostName().size()) - { - return; - } - - //LL_INFOS() << "LLAres::rewriteURI (" << uri << ") search: '" << "_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName() << "'" << LL_ENDL; - - search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(), RES_SRV, resp); - - - } -} - -LLQueryResponder::LLQueryResponder() - : LLAres::QueryResponder(), - mResult(ARES_ENODATA), - mType(RES_INVALID) -{ -} - -int LLQueryResponder::parseRR(const char *buf, size_t len, const char *&pos, - LLPointer<LLDnsRecord> &r) -{ - std::string rrname; - size_t enclen; - int ret; - - // RR name. - - ret = LLAres::expandName(pos, buf, len, rrname, enclen); - if (ret != ARES_SUCCESS) - { - return ret; - } - - pos += enclen; - - if (pos + NS_RRFIXEDSZ > buf + len) - { - return ARES_EBADRESP; - } - - int rrtype = DNS_RR_TYPE(pos); - int rrclass = DNS_RR_CLASS(pos); - int rrttl = DNS_RR_TTL(pos); - int rrlen = DNS_RR_LEN(pos); - - if (rrclass != ns_c_in) - { - return ARES_EBADRESP; - } - - pos += NS_RRFIXEDSZ; - - if (pos + rrlen > buf + len) - { - return ARES_EBADRESP; - } - - switch (rrtype) - { - case RES_A: - r = new LLARecord(rrname, rrttl); - break; - case RES_NS: - r = new LLNsRecord(rrname, rrttl); - break; - case RES_CNAME: - r = new LLCnameRecord(rrname, rrttl); - break; - case RES_PTR: - r = new LLPtrRecord(rrname, rrttl); - break; - case RES_AAAA: - r = new LLAaaaRecord(rrname, rrttl); - break; - case RES_SRV: - r = new LLSrvRecord(rrname, rrttl); - break; - default: - LL_INFOS() << "LLQueryResponder::parseRR got unknown RR type " << rrtype - << LL_ENDL; - return ARES_EBADRESP; - } - - ret = r->parse(buf, len, pos, rrlen); - - if (ret == ARES_SUCCESS) - { - pos += rrlen; - } else { - r = NULL; - } - - return ret; -} - -int LLQueryResponder::parseSection(const char *buf, size_t len, - size_t count, const char *&pos, - dns_rrs_t &rrs) -{ - int ret = ARES_SUCCESS; - - for (size_t i = 0; i < count; i++) - { - LLPointer<LLDnsRecord> r; - ret = parseRR(buf, len, pos, r); - if (ret != ARES_SUCCESS) - { - break; - } - rrs.push_back(r); - } - - return ret; -} - -void LLQueryResponder::queryResult(const char *buf, size_t len) -{ - const char *pos = buf; - int qdcount = DNS_HEADER_QDCOUNT(pos); - int ancount = DNS_HEADER_ANCOUNT(pos); - int nscount = DNS_HEADER_NSCOUNT(pos); - int arcount = DNS_HEADER_ARCOUNT(pos); - int ret; - - if (qdcount == 0 || ancount + nscount + arcount == 0) - { - ret = ARES_ENODATA; - goto bail; - } - - pos += NS_HFIXEDSZ; - - for (int i = 0; i < qdcount; i++) - { - std::string ignore; - size_t enclen; - - ret = LLAres::expandName(pos, buf, len, i == 0 ? mQuery : ignore, - enclen); - if (ret != ARES_SUCCESS) - { - goto bail; - } - - pos += enclen; - - if (i == 0) - { - int t = DNS_QUESTION_TYPE(pos); - switch (t) - { - case RES_A: - case RES_NS: - case RES_CNAME: - case RES_PTR: - case RES_AAAA: - case RES_SRV: - mType = (LLResType) t; - break; - default: - LL_INFOS() << "Cannot grok query type " << t << LL_ENDL; - ret = ARES_EBADQUERY; - goto bail; - } - } - - pos += NS_QFIXEDSZ; - if (pos > buf + len) - { - ret = ARES_EBADRESP; - goto bail; - } - } - - ret = parseSection(buf, len, ancount, pos, mAnswers); - if (ret != ARES_SUCCESS) - { - goto bail; - } - - ret = parseSection(buf, len, nscount, pos, mAuthorities); - if (ret != ARES_SUCCESS) - { - goto bail; - } - - ret = parseSection(buf, len, arcount, pos, mAdditional); - -bail: - mResult = ret; - if (mResult == ARES_SUCCESS) - { - querySuccess(); - } else { - queryError(mResult); - } -} - -void LLQueryResponder::querySuccess() -{ - LL_INFOS() << "LLQueryResponder::queryResult not implemented" << LL_ENDL; -} - -void LLAres::SrvResponder::querySuccess() -{ - if (mType == RES_SRV) - { - srvResult(mAnswers); - } else { - srvError(ARES_EBADRESP); - } -} - -void LLAres::SrvResponder::queryError(int code) -{ - srvError(code); -} - -void LLAres::SrvResponder::srvResult(const dns_rrs_t &ents) -{ - LL_INFOS() << "LLAres::SrvResponder::srvResult not implemented" << LL_ENDL; - - for (size_t i = 0; i < ents.size(); i++) - { - const LLSrvRecord *s = (const LLSrvRecord *) ents[i].get(); - - LL_INFOS() << "[" << i << "] " << s->host() << ":" << s->port() - << " priority " << s->priority() - << " weight " << s->weight() - << LL_ENDL; - } -} - -void LLAres::SrvResponder::srvError(int code) -{ - LL_INFOS() << "LLAres::SrvResponder::srvError " << code << ": " - << LLAres::strerror(code) << LL_ENDL; -} - -static void nameinfo_callback_1_5(void *arg, int status, int timeouts, - char *node, char *service) -{ - LLPointer<LLAres::NameInfoResponder> *resp = - (LLPointer<LLAres::NameInfoResponder> *) arg; - - if (status == ARES_SUCCESS) - { - (*resp)->nameInfoResult(node, service); - } else { - (*resp)->nameInfoError(status); - } - - delete resp; -} - -#if ARES_VERSION_MAJOR == 1 && ARES_VERSION_MINOR == 4 -static void nameinfo_callback(void *arg, int status, char *node, char *service) -{ - nameinfo_callback_1_5(arg, status, 0, node, service); -} -#else -# define nameinfo_callback nameinfo_callback_1_5 -#endif - -void LLAres::getNameInfo(const struct sockaddr &sa, socklen_t salen, int flags, - NameInfoResponder *resp) -{ - ares_getnameinfo(chan_, &sa, salen, flags, nameinfo_callback, - new LLPointer<NameInfoResponder>(resp)); -} - -static void search_callback_1_5(void *arg, int status, int timeouts, - unsigned char *abuf, int alen) -{ - LLPointer<LLAres::QueryResponder> *resp = - (LLPointer<LLAres::QueryResponder> *) arg; - - if (status == ARES_SUCCESS) - { - (*resp)->queryResult((const char *) abuf, alen); - } else { - (*resp)->queryError(status); - } - - delete resp; -} - -#if ARES_VERSION_MAJOR == 1 && ARES_VERSION_MINOR == 4 -static void search_callback(void *arg, int status, unsigned char *abuf, - int alen) -{ - search_callback_1_5(arg, status, 0, abuf, alen); -} -#else -# define search_callback search_callback_1_5 -#endif - -void LLAres::search(const std::string &query, LLResType type, - QueryResponder *resp) -{ - ares_search(chan_, query.c_str(), ns_c_in, type, search_callback, - new LLPointer<QueryResponder>(resp)); -} - -bool LLAres::process(U64 timeout) -{ - if (!gAPRPoolp) - { - ll_init_apr(); - } - - ares_socket_t socks[ARES_GETSOCK_MAXNUM]; - apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM]; - apr_int32_t nsds = 0; - int nactive = 0; - int bitmask; - - bitmask = ares_getsock(chan_, socks, ARES_GETSOCK_MAXNUM); - - if (bitmask == 0) - { - return nsds > 0; - } - - apr_status_t status; - LLAPRPool pool; - status = pool.getStatus() ; - ll_apr_assert_status(status); - - for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++) - { - if (ARES_GETSOCK_READABLE(bitmask, i)) - { - aprFds[nactive].reqevents = APR_POLLIN | APR_POLLERR; - } - else if (ARES_GETSOCK_WRITABLE(bitmask, i)) - { - aprFds[nactive].reqevents = APR_POLLOUT | APR_POLLERR; - } else { - continue; - } - - apr_socket_t *aprSock = NULL; - - status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool()); - if (status != APR_SUCCESS) - { - ll_apr_warn_status(status); - return nsds > 0; - } - - aprFds[nactive].desc.s = aprSock; - aprFds[nactive].desc_type = APR_POLL_SOCKET; - aprFds[nactive].p = pool.getAPRPool(); - aprFds[nactive].rtnevents = 0; - aprFds[nactive].client_data = &socks[i]; - - nactive++; - } - - if (nactive > 0) - { - status = apr_poll(aprFds, nactive, &nsds, timeout); - - if (status != APR_SUCCESS && status != APR_TIMEUP) - { - ll_apr_warn_status(status); - } - - for (int i = 0; i < nactive; i++) - { - int evts = aprFds[i].rtnevents; - int ifd = (evts & (APR_POLLIN | APR_POLLERR)) - ? *((int *) aprFds[i].client_data) : ARES_SOCKET_BAD; - int ofd = (evts & (APR_POLLOUT | APR_POLLERR)) - ? *((int *) aprFds[i].client_data) : ARES_SOCKET_BAD; - - ares_process_fd(chan_, ifd, ofd); - } - } - - return nsds > 0; -} - -bool LLAres::processAll() -{ - bool anyProcessed = false, ret; - - do { - timeval tv; - - ret = ares_timeout(chan_, NULL, &tv) != NULL; - - if (ret) - { - ret = process(tv.tv_sec * 1000000LL + tv.tv_usec); - anyProcessed |= ret; - } - } while (ret); - - return anyProcessed; -} - -int LLAres::expandName(const char *encoded, const char *abuf, size_t alen, - std::string &s, size_t &enclen) -{ - char *t; - int ret; - long e; - - ret = ares_expand_name((const unsigned char *) encoded, - (const unsigned char *) abuf, alen, &t, &e); - if (ret == ARES_SUCCESS) - { - s.assign(t); - enclen = e; - ares_free_string(t); - } - return ret; -} - -const char *LLAres::strerror(int code) -{ - return ares_strerror(code); -} - -LLAres *gAres; - -LLAres *ll_init_ares() -{ - if (gAres == NULL) - { - gAres = new LLAres(); - } - return gAres; -} - -void ll_cleanup_ares() -{ - if (gAres != NULL) - { - delete gAres; - gAres = NULL; - } -} - -LLDnsRecord::LLDnsRecord(LLResType type, const std::string &name, - unsigned ttl) - : LLRefCount(), - mType(type), - mName(name), - mTTL(ttl) -{ -} - -LLHostRecord::LLHostRecord(LLResType type, const std::string &name, - unsigned ttl) - : LLDnsRecord(type, name, ttl) -{ -} - -int LLHostRecord::parse(const char *buf, size_t len, const char *pos, - size_t rrlen) -{ - int ret; - - ret = LLAres::expandName(pos, buf, len, mHost); - if (ret != ARES_SUCCESS) - { - goto bail; - } - - ret = ARES_SUCCESS; - -bail: - return ret; -} - -LLCnameRecord::LLCnameRecord(const std::string &name, unsigned ttl) - : LLHostRecord(RES_CNAME, name, ttl) -{ -} - -LLPtrRecord::LLPtrRecord(const std::string &name, unsigned ttl) - : LLHostRecord(RES_PTR, name, ttl) -{ -} - -LLAddrRecord::LLAddrRecord(LLResType type, const std::string &name, - unsigned ttl) - : LLDnsRecord(type, name, ttl), - - mSize(0) -{ -} - -LLARecord::LLARecord(const std::string &name, unsigned ttl) - : LLAddrRecord(RES_A, name, ttl) -{ -} - -int LLARecord::parse(const char *buf, size_t len, const char *pos, - size_t rrlen) -{ - int ret; - - if (rrlen != sizeof(mSA.sin.sin_addr.s_addr)) - { - ret = ARES_EBADRESP; - goto bail; - } - - memset(&mSA, 0, sizeof(mSA)); - memcpy(&mSA.sin.sin_addr.s_addr, pos, rrlen); - mSA.sin.sin_family = AF_INET6; - mSize = sizeof(mSA.sin); - - ret = ARES_SUCCESS; - -bail: - return ret; -} - -LLAaaaRecord::LLAaaaRecord(const std::string &name, unsigned ttl) - : LLAddrRecord(RES_AAAA, name, ttl) -{ -} - -int LLAaaaRecord::parse(const char *buf, size_t len, const char *pos, - size_t rrlen) -{ - int ret; - - if (rrlen != sizeof(mSA.sin6.sin6_addr)) - { - ret = ARES_EBADRESP; - goto bail; - } - - memset(&mSA, 0, sizeof(mSA)); - memcpy(&mSA.sin6.sin6_addr.s6_addr, pos, rrlen); - mSA.sin6.sin6_family = AF_INET6; - mSize = sizeof(mSA.sin6); - - ret = ARES_SUCCESS; - -bail: - return ret; -} - -LLSrvRecord::LLSrvRecord(const std::string &name, unsigned ttl) - : LLHostRecord(RES_SRV, name, ttl), - - mPriority(0), - mWeight(0), - mPort(0) -{ -} - -int LLSrvRecord::parse(const char *buf, size_t len, const char *pos, - size_t rrlen) -{ - int ret; - - if (rrlen < 6) - { - ret = ARES_EBADRESP; - goto bail; - } - - memcpy(&mPriority, pos, 2); - memcpy(&mWeight, pos + 2, 2); - memcpy(&mPort, pos + 4, 2); - - mPriority = ntohs(mPriority); - mWeight = ntohs(mWeight); - mPort = ntohs(mPort); - - ret = LLHostRecord::parse(buf, len, pos + 6, rrlen - 6); - -bail: - return ret; -} - -LLNsRecord::LLNsRecord(const std::string &name, unsigned ttl) - : LLHostRecord(RES_NS, name, ttl) -{ -} - -void LLAres::UriRewriteResponder::queryError(int code) -{ - std::vector<std::string> uris; - uris.push_back(mUri.asString()); - rewriteResult(uris); -} - -void LLAres::UriRewriteResponder::querySuccess() -{ - std::vector<std::string> uris; - - if (mType != RES_SRV) - { - goto bail; - } - - for (size_t i = 0; i < mAnswers.size(); i++) - { - const LLSrvRecord *r = (const LLSrvRecord *) mAnswers[i].get(); - - if (r->type() == RES_SRV) - { - // Check the domain in the response to ensure that it's - // the same as the domain in the request, so that bad guys - // can't forge responses that point to their own login - // servers with their own certificates. - - // Hard-coding the domain to check here is a bit of a - // hack. Hoist it to an outer caller if anyone ever needs - // this functionality on other domains. - - static const std::string domain(".lindenlab.com"); - const std::string &host = r->host(); - - std::string::size_type s = host.find(domain) + domain.length(); - - if (s != host.length() && s != host.length() - 1) - { - continue; - } - - LLURI uri(mUri.scheme(), - mUri.userName(), - mUri.password(), - r->host(), - mUri.defaultPort() ? r->port() : mUri.hostPort(), - mUri.escapedPath(), - mUri.escapedQuery()); - uris.push_back(uri.asString()); - } - } - - if (!uris.empty()) - { - goto done; - } - -bail: - uris.push_back(mUri.asString()); - -done: - rewriteResult(uris); -} - -void LLAres::UriRewriteResponder::rewriteResult( - const std::vector<std::string> &uris) -{ - LL_INFOS() << "LLAres::UriRewriteResponder::rewriteResult not implemented" - << LL_ENDL; - - for (size_t i = 0; i < uris.size(); i++) - { - LL_INFOS() << "[" << i << "] " << uris[i] << LL_ENDL; - } -} diff --git a/indra/llmessage/llares.h b/indra/llmessage/llares.h deleted file mode 100755 index c727363b60..0000000000 --- a/indra/llmessage/llares.h +++ /dev/null @@ -1,583 +0,0 @@ -/** - * @file llares.h - * @author Bryan O'Sullivan - * @date 2007-08-15 - * @brief Wrapper for asynchronous DNS lookups. - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLARES_H -#define LL_LLARES_H - -#ifdef LL_WINDOWS -// ares.h is broken on windows in that it depends on types defined in ws2tcpip.h -// we need to include them first to work around it, but the headers issue warnings -# pragma warning(push) -# pragma warning(disable:4996) -# include <winsock2.h> -# include <ws2tcpip.h> -# pragma warning(pop) -#endif - -#ifdef LL_USESYSTEMLIBS -# include <ares.h> -#else -# include <ares/ares.h> -#endif - -#include "llpointer.h" -#include "llrefcount.h" -#include "lluri.h" - -#include <boost/shared_ptr.hpp> - -class LLQueryResponder; -class LLAresListener; - -/** - * @brief Supported DNS RR types. - */ -enum LLResType -{ - RES_INVALID = 0, /**< Cookie. */ - RES_A = 1, /**< "A" record. IPv4 address. */ - RES_NS = 2, /**< "NS" record. Authoritative server. */ - RES_CNAME = 5, /**< "CNAME" record. Canonical name. */ - RES_PTR = 12, /**< "PTR" record. Domain name pointer. */ - RES_AAAA = 28, /**< "AAAA" record. IPv6 Address. */ - RES_SRV = 33, /**< "SRV" record. Server Selection. */ - RES_MAX = 65536 /**< Sentinel; RR types are 16 bits wide. */ -}; - -/** - * @class LLDnsRecord - * @brief Base class for all DNS RR types. - */ -class LLDnsRecord : public LLRefCount -{ -protected: - friend class LLQueryResponder; - - LLResType mType; - std::string mName; - unsigned mTTL; - - virtual int parse(const char *buf, size_t len, const char *pos, - size_t rrlen) = 0; - - LLDnsRecord(LLResType type, const std::string &name, unsigned ttl); - -public: - /** - * @brief Record name. - */ - const std::string &name() const { return mName; } - - /** - * @brief Time-to-live value, in seconds. - */ - unsigned ttl() const { return mTTL; } - - /** - * @brief RR type. - */ - LLResType type() const { return mType; } -}; - -/** - * @class LLAddrRecord - * @brief Base class for address-related RRs. - */ -class LLAddrRecord : public LLDnsRecord -{ -protected: - friend class LLQueryResponder; - - LLAddrRecord(LLResType type, const std::string &name, unsigned ttl); - - union - { - sockaddr sa; - sockaddr_in sin; - sockaddr_in6 sin6; - } mSA; - - socklen_t mSize; - -public: - /** - * @brief Generic socket address. - */ - const sockaddr &addr() const { return mSA.sa; } - - /** - * @brief Size of the socket structure. - */ - socklen_t size() const { return mSize; } -}; - -/** - * @class LLARecord - * @brief A RR, for IPv4 addresses. - */ -class LLARecord : public LLAddrRecord -{ -protected: - friend class LLQueryResponder; - - LLARecord(const std::string &name, unsigned ttl); - - int parse(const char *buf, size_t len, const char *pos, size_t rrlen); - -public: - /** - * @brief Socket address. - */ - const sockaddr_in &addr_in() const { return mSA.sin; } -}; - -/** - * @class LLAaaaRecord - * @brief AAAA RR, for IPv6 addresses. - */ -class LLAaaaRecord : public LLAddrRecord -{ -protected: - friend class LLQueryResponder; - - LLAaaaRecord(const std::string &name, unsigned ttl); - - int parse(const char *buf, size_t len, const char *pos, size_t rrlen); - -public: - /** - * @brief Socket address. - */ - const sockaddr_in6 &addr_in6() const { return mSA.sin6; } -}; - -/** - * @class LLHostRecord - * @brief Base class for host-related RRs. - */ -class LLHostRecord : public LLDnsRecord -{ -protected: - LLHostRecord(LLResType type, const std::string &name, unsigned ttl); - - int parse(const char *buf, size_t len, const char *pos, size_t rrlen); - - std::string mHost; - -public: - /** - * @brief Host name. - */ - const std::string &host() const { return mHost; } -}; - -/** - * @class LLCnameRecord - * @brief CNAME RR. - */ -class LLCnameRecord : public LLHostRecord -{ -protected: - friend class LLQueryResponder; - - LLCnameRecord(const std::string &name, unsigned ttl); -}; - -/** - * @class LLPtrRecord - * @brief PTR RR. - */ -class LLPtrRecord : public LLHostRecord -{ -protected: - friend class LLQueryResponder; - - LLPtrRecord(const std::string &name, unsigned ttl); -}; - -/** - * @class LLSrvRecord - * @brief SRV RR. - */ -class LLSrvRecord : public LLHostRecord -{ -protected: - U16 mPriority; - U16 mWeight; - U16 mPort; - - int parse(const char *buf, size_t len, const char *pos, size_t rrlen); - -public: - LLSrvRecord(const std::string &name, unsigned ttl); - - /** - * @brief Service priority. - */ - U16 priority() const { return mPriority; } - - /** - * @brief Service weight. - */ - U16 weight() const { return mWeight; } - - /** - * @brief Port number of service. - */ - U16 port() const { return mPort; } - - /** - * @brief Functor for sorting SRV records by priority. - */ - struct ComparePriorityLowest - { - bool operator()(const LLSrvRecord& lhs, const LLSrvRecord& rhs) - { - return lhs.mPriority < rhs.mPriority; - } - }; -}; - -/** - * @class LLNsRecord - * @brief NS RR. - */ -class LLNsRecord : public LLHostRecord -{ -public: - LLNsRecord(const std::string &name, unsigned ttl); -}; - -class LLQueryResponder; - -/** - * @class LLAres - * @brief Asynchronous address resolver. - */ -class LLAres -{ -public: - /** - * @class HostResponder - * @brief Base class for responding to hostname lookups. - * @see LLAres::getHostByName - */ - class HostResponder : public LLRefCount - { - public: - virtual ~HostResponder(); - - virtual void hostResult(const hostent *ent); - virtual void hostError(int code); - }; - - /** - * @class NameInfoResponder - * @brief Base class for responding to address lookups. - * @see LLAres::getNameInfo - */ - class NameInfoResponder : public LLRefCount - { - public: - virtual ~NameInfoResponder(); - - virtual void nameInfoResult(const char *node, const char *service); - virtual void nameInfoError(int code); - }; - - /** - * @class QueryResponder - * @brief Base class for responding to custom searches. - * @see LLAres::search - */ - class QueryResponder : public LLRefCount - { - public: - virtual ~QueryResponder(); - - virtual void queryResult(const char *buf, size_t len); - virtual void queryError(int code); - }; - - class SrvResponder; - class UriRewriteResponder; - - LLAres(); - - ~LLAres(); - - /** - * Cancel all outstanding requests. The error methods of the - * corresponding responders will be called, with ARES_ETIMEOUT. - */ - void cancel(); - - /** - * Look up the address of a host. - * - * @param name name of host to look up - * @param resp responder to call with result - * @param family AF_INET for IPv4 addresses, AF_INET6 for IPv6 - */ - void getHostByName(const std::string &name, HostResponder *resp, - int family = AF_INET) { - getHostByName(name.c_str(), resp, family); - } - - /** - * Look up the address of a host. - * - * @param name name of host to look up - * @param resp responder to call with result - * @param family AF_INET for IPv4 addresses, AF_INET6 for IPv6 - */ - void getHostByName(const char *name, HostResponder *resp, - int family = PF_INET); - - /** - * Look up the name associated with a socket address. - * - * @param sa socket address to look up - * @param salen size of socket address - * @param flags flags to use - * @param resp responder to call with result - */ - void getNameInfo(const struct sockaddr &sa, socklen_t salen, int flags, - NameInfoResponder *resp); - - /** - * Look up SRV (service location) records for a service name. - * - * @param name service name (e.g. "_https._tcp.login.agni.lindenlab.com") - * @param resp responder to call with result - */ - void getSrvRecords(const std::string &name, SrvResponder *resp); - - /** - * Rewrite a URI, using SRV (service location) records for its - * protocol if available. If no SRV records are published, the - * existing URI is handed to the responder. - * - * @param uri URI to rewrite - * @param resp responder to call with result - */ - void rewriteURI(const std::string &uri, - UriRewriteResponder *resp); - - /** - * Start a custom search. - * - * @param query query to make - * @param type type of query to perform - * @param resp responder to call with result - */ - void search(const std::string &query, LLResType type, - QueryResponder *resp); - - /** - * Process any outstanding queries. This method takes an optional - * timeout parameter (specified in microseconds). If provided, it - * will block the calling thread for that length of time to await - * possible responses. A timeout of zero will return immediately - * if there are no responses or timeouts to process. - * - * @param timeoutUsecs number of microseconds to block before timing out - * @return whether any responses were processed - */ - bool process(U64 timeoutUsecs = 0); - - /** - * Process all outstanding queries, blocking the calling thread - * until all have either been responded to or timed out. - * - * @return whether any responses were processed - */ - bool processAll(); - - /** - * Expand a DNS-encoded compressed string into a normal string. - * - * @param encoded the encoded name (null-terminated) - * @param abuf the response buffer in which the string is embedded - * @param alen the length of the response buffer - * @param s the string into which to place the result - * @return ARES_SUCCESS on success, otherwise an error indicator - */ - static int expandName(const char *encoded, const char *abuf, size_t alen, - std::string &s) { - size_t ignore; - return expandName(encoded, abuf, alen, s, ignore); - } - - static int expandName(const char *encoded, const char *abuf, size_t alen, - std::string &s, size_t &enclen); - - /** - * Return a string describing an error code. - */ - static const char *strerror(int code); - - bool isInitialized(void) { return mInitSuccess; } - -protected: - ares_channel chan_; - bool mInitSuccess; - // boost::scoped_ptr would actually fit the requirement better, but it - // can't handle incomplete types as boost::shared_ptr can. - boost::shared_ptr<LLAresListener> mListener; -}; - -/** - * An ordered collection of DNS resource records. - */ -typedef std::vector<LLPointer<LLDnsRecord> > dns_rrs_t; - -/** - * @class LLQueryResponder - * @brief Base class for friendly handling of DNS query responses. - * - * This class parses a DNS response and represents it in a friendly - * manner. - * - * @see LLDnsRecord - * @see LLARecord - * @see LLNsRecord - * @see LLCnameRecord - * @see LLPtrRecord - * @see LLAaaaRecord - * @see LLSrvRecord - */ -class LLQueryResponder : public LLAres::QueryResponder -{ -protected: - int mResult; - std::string mQuery; - LLResType mType; - - dns_rrs_t mAnswers; - dns_rrs_t mAuthorities; - dns_rrs_t mAdditional; - - /** - * Parse a single RR. - */ - int parseRR(const char *buf, size_t len, const char *&pos, - LLPointer<LLDnsRecord> &r); - /** - * Parse one section of a response. - */ - int parseSection(const char *buf, size_t len, - size_t count, const char *& pos, dns_rrs_t &rrs); - - void queryResult(const char *buf, size_t len); - virtual void querySuccess(); - -public: - LLQueryResponder(); - - /** - * Indicate whether the response could be parsed successfully. - */ - bool valid() const { return mResult == ARES_SUCCESS; } - - /** - * The more detailed result of parsing the response. - */ - int result() const { return mResult; } - - /** - * Return the query embedded in the response. - */ - const std::string &query() const { return mQuery; } - - /** - * Return the contents of the "answers" section of the response. - */ - const dns_rrs_t &answers() const { return mAnswers; } - - /** - * Return the contents of the "authorities" section of the - * response. - */ - const dns_rrs_t &authorities() const { return mAuthorities; } - - /** - * Return the contents of the "additional records" section of the - * response. - */ - const dns_rrs_t &additional() const { return mAdditional; } -}; - -/** - * @class LLAres::SrvResponder - * @brief Class for handling SRV query responses. - */ -class LLAres::SrvResponder : public LLQueryResponder -{ -public: - friend void LLAres::getSrvRecords(const std::string &name, - SrvResponder *resp); - void querySuccess(); - void queryError(int code); - - virtual void srvResult(const dns_rrs_t &ents); - virtual void srvError(int code); -}; - -/** - * @class LLAres::UriRewriteResponder - * @brief Class for handling URI rewrites based on SRV records. - */ -class LLAres::UriRewriteResponder : public LLQueryResponder -{ -protected: - LLURI mUri; - -public: - friend void LLAres::rewriteURI(const std::string &uri, - UriRewriteResponder *resp); - void querySuccess(); - void queryError(int code); - - virtual void rewriteResult(const std::vector<std::string> &uris); -}; - -/** - * Singleton responder. - */ -extern LLAres *gAres; - -/** - * Set up the singleton responder. It's safe to call this more than - * once from within a single thread, but this function is not - * thread safe. - */ -extern LLAres *ll_init_ares(); -extern void ll_cleanup_ares(); - -#endif // LL_LLARES_H diff --git a/indra/llmessage/llareslistener.cpp b/indra/llmessage/llareslistener.cpp deleted file mode 100755 index 3d65906b98..0000000000 --- a/indra/llmessage/llareslistener.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @file llareslistener.cpp - * @author Nat Goodspeed - * @date 2009-03-18 - * @brief Implementation for llareslistener. - * - * $LicenseInfo:firstyear=2009&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -// Precompiled header -#include "linden_common.h" -// associated header -#include "llareslistener.h" -// STL headers -// std headers -// external library headers -// other Linden headers -#include "llares.h" -#include "llerror.h" -#include "llevents.h" -#include "llsdutil.h" - -LLAresListener::LLAresListener(LLAres* llares): - LLEventAPI("LLAres", - "LLAres listener to request DNS operations"), - mAres(llares) -{ - // add() every method we want to be able to invoke via this event API. - // Optional last parameter validates expected LLSD request structure. - add("rewriteURI", - "Given [\"uri\"], return on [\"reply\"] an array of alternative URIs.\n" - "On failure, returns an array containing only the original URI, so\n" - "failure case can be processed like success case.", - &LLAresListener::rewriteURI, - LLSD().with("uri", LLSD()).with("reply", LLSD())); -} - -/// This UriRewriteResponder subclass packages returned URIs as an LLSD -/// array to send back to the requester. -class UriRewriteResponder: public LLAres::UriRewriteResponder -{ -public: - /** - * Specify the request, containing the event pump name on which to send - * the reply. - */ - UriRewriteResponder(const LLSD& request): - mReqID(request), - mPumpName(request["reply"]) - {} - - /// Called by base class with results. This is called in both the - /// success and error cases. On error, the calling logic passes the - /// original URI. - virtual void rewriteResult(const std::vector<std::string>& uris) - { - LLSD result; - for (std::vector<std::string>::const_iterator ui(uris.begin()), uend(uris.end()); - ui != uend; ++ui) - { - result.append(*ui); - } - // This call knows enough to avoid trying to insert a map key into an - // LLSD array. It's there so that if, for any reason, we ever decide - // to change the response from array to map, it will Just Start Working. - mReqID.stamp(result); - LLEventPumps::instance().obtain(mPumpName).post(result); - } - -private: - LLReqID mReqID; - const std::string mPumpName; -}; - -void LLAresListener::rewriteURI(const LLSD& data) -{ - if (mAres) - { - mAres->rewriteURI(data["uri"], new UriRewriteResponder(data)); - } - else - { - LL_INFOS() << "LLAresListener::rewriteURI requested without Ares present. Ignoring: " << data << LL_ENDL; - } -} diff --git a/indra/llmessage/llareslistener.h b/indra/llmessage/llareslistener.h deleted file mode 100755 index 780dcdd9c5..0000000000 --- a/indra/llmessage/llareslistener.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file llareslistener.h - * @author Nat Goodspeed - * @date 2009-03-18 - * @brief LLEventPump API for LLAres. This header doesn't actually define the - * API; the API is defined by the pump name on which this class - * listens, and by the expected content of LLSD it receives. - * - * $LicenseInfo:firstyear=2009&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#if ! defined(LL_LLARESLISTENER_H) -#define LL_LLARESLISTENER_H - -#include "lleventapi.h" - -class LLAres; -class LLSD; - -/// Listen on an LLEventPump with specified name for LLAres request events. -class LLAresListener: public LLEventAPI -{ -public: - /// Bind the LLAres instance to use (e.g. gAres) - LLAresListener(LLAres* llares); - -private: - /// command["op"] == "rewriteURI" - void rewriteURI(const LLSD& data); - - LLAres* mAres; -}; - -#endif /* ! defined(LL_LLARESLISTENER_H) */ |