diff options
Diffstat (limited to 'indra/llmessage')
-rw-r--r-- | indra/llmessage/CMakeLists.txt | 191 | ||||
-rw-r--r-- | indra/llmessage/llares.cpp | 804 | ||||
-rw-r--r-- | indra/llmessage/llares.h | 572 | ||||
-rw-r--r-- | indra/llmessage/llfiltersd2xmlrpc.cpp | 2 | ||||
-rw-r--r-- | indra/llmessage/lliopipe.h | 2 | ||||
-rw-r--r-- | indra/llmessage/lliosocket.cpp | 2 | ||||
-rw-r--r-- | indra/llmessage/lliosocket.h | 4 | ||||
-rw-r--r-- | indra/llmessage/llmail.cpp | 25 | ||||
-rw-r--r-- | indra/llmessage/llmessagetemplateparser.cpp | 2 | ||||
-rw-r--r-- | indra/llmessage/llpumpio.cpp | 13 | ||||
-rw-r--r-- | indra/llmessage/llpumpio.h | 2 | ||||
-rwxr-xr-x | indra/llmessage/llsdmessagereader.cpp | 7 | ||||
-rw-r--r-- | indra/llmessage/llurlrequest.cpp | 2 | ||||
-rw-r--r-- | indra/llmessage/message.cpp | 30 | ||||
-rw-r--r-- | indra/llmessage/message.h | 14 |
15 files changed, 1635 insertions, 37 deletions
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt new file mode 100644 index 0000000000..ba17265a66 --- /dev/null +++ b/indra/llmessage/CMakeLists.txt @@ -0,0 +1,191 @@ +# -*- cmake -*- + +project(llmessage) + +include(00-Common) +include(LLCommon) +include(LLMath) +include(LLMessage) +include(LLVFS) + +include_directories (${CMAKE_CURRENT_SOURCE_DIR}) + +include_directories( + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLMESSAGE_INCLUDE_DIRS} + ${LLVFS_INCLUDE_DIRS} + ) + +set(llmessage_SOURCE_FILES + llares.cpp + llassetstorage.cpp + llblowfishcipher.cpp + llbuffer.cpp + llbufferstream.cpp + llcachename.cpp + llchainio.cpp + llcircuit.cpp + llclassifiedflags.cpp + llcurl.cpp + lldatapacker.cpp + lldispatcher.cpp + llfiltersd2xmlrpc.cpp + llhost.cpp + llhttpassetstorage.cpp + llhttpclient.cpp + llhttpnode.cpp + llhttpsender.cpp + llinstantmessage.cpp + lliobuffer.cpp + lliohttpserver.cpp + lliopipe.cpp + lliosocket.cpp + llioutil.cpp + llmail.cpp + llmessagebuilder.cpp + llmessageconfig.cpp + llmessagereader.cpp + llmessagetemplate.cpp + llmessagetemplateparser.cpp + llmessagethrottle.cpp + llmime.cpp + llnamevalue.cpp + llnullcipher.cpp + llpacketack.cpp + llpacketbuffer.cpp + llpacketring.cpp + llpartdata.cpp + llpumpio.cpp + llsdappservices.cpp + llsdhttpserver.cpp + llsdmessagebuilder.cpp + llsdmessagereader.cpp + llsdrpcclient.cpp + llsdrpcserver.cpp + llservicebuilder.cpp + llservice.cpp + lltemplatemessagebuilder.cpp + lltemplatemessagereader.cpp + llthrottle.cpp + lltransfermanager.cpp + lltransfersourceasset.cpp + lltransfersourcefile.cpp + lltransfertargetfile.cpp + lltransfertargetvfile.cpp + llurlrequest.cpp + lluseroperation.cpp + llxfer.cpp + llxfer_file.cpp + llxfermanager.cpp + llxfer_mem.cpp + llxfer_vfile.cpp + llxorcipher.cpp + message.cpp + message_prehash.cpp + message_string_table.cpp + net.cpp + network.cpp + partsyspacket.cpp + patch_code.cpp + patch_dct.cpp + patch_idct.cpp + ) + +set(llmessage_HEADER_FILES + CMakeLists.txt + + llares.h + llassetstorage.h + llblowfishcipher.h + llbuffer.h + llbufferstream.h + llcachename.h + llchainio.h + llcipher.h + llcircuit.h + llclassifiedflags.h + llcurl.h + lldatapacker.h + lldbstrings.h + lldispatcher.h + lleventflags.h + llfiltersd2xmlrpc.h + llfollowcamparams.h + llhost.h + llhttpassetstorage.h + llhttpclient.h + llhttpnode.h + llhttpsender.h + llinstantmessage.h + llinvite.h + lliobuffer.h + lliohttpserver.h + lliopipe.h + lliosocket.h + llioutil.h + llloginflags.h + llmail.h + llmessagebuilder.h + llmessageconfig.h + llmessagereader.h + llmessagetemplate.h + llmessagetemplateparser.h + llmessagethrottle.h + llmime.h + llmsgvariabletype.h + llnamevalue.h + llnullcipher.h + llpacketack.h + llpacketbuffer.h + llpacketring.h + llpartdata.h + llpumpio.h + llqueryflags.h + llregionflags.h + llregionhandle.h + llsdappservices.h + llsdhttpserver.h + llsdmessagebuilder.h + llsdmessagereader.h + llsdrpcclient.h + llsdrpcserver.h + llservice.h + llservicebuilder.h + lltaskname.h + llteleportflags.h + lltemplatemessagebuilder.h + lltemplatemessagereader.h + llthrottle.h + lltransfermanager.h + lltransfersourceasset.h + lltransfersourcefile.h + lltransfertargetfile.h + lltransfertargetvfile.h + llurlrequest.h + lluseroperation.h + llvehicleparams.h + llxfer.h + llxfermanager.h + llxfer_file.h + llxfer_mem.h + llxfer_vfile.h + llxorcipher.h + machine.h + mean_collision_data.h + message.h + message_prehash.h + net.h + network.h + partsyspacket.h + patch_code.h + patch_dct.h + sound_ids.h + ) + +set_source_files_properties(${llmessage_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND llmessage_SOURCE_FILES ${llmessage_HEADER_FILES}) + +add_library (llmessage ${llmessage_SOURCE_FILES}) diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp new file mode 100644 index 0000000000..d11f227c21 --- /dev/null +++ b/indra/llmessage/llares.cpp @@ -0,0 +1,804 @@ +/** + * @file llares.cpp + * @author Bryan O'Sullivan + * @date 2007-08-15 + * @brief Wrapper for asynchronous DNS lookups. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.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 "llares.h" + +#if defined(LL_WINDOWS) +# 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) +{ + llinfos << "LLAres::HostResponder::hostResult not implemented" << llendl; +} + +void LLAres::HostResponder::hostError(int code) +{ + llinfos << "LLAres::HostResponder::hostError " << code << ": " + << LLAres::strerror(code) << llendl; +} + +LLAres::NameInfoResponder::~NameInfoResponder() +{ +} + +void LLAres::NameInfoResponder::nameInfoResult(const char *node, + const char *service) +{ + llinfos << "LLAres::NameInfoResponder::nameInfoResult not implemented" + << llendl; +} + +void LLAres::NameInfoResponder::nameInfoError(int code) +{ + llinfos << "LLAres::NameInfoResponder::nameInfoError " << code << ": " + << LLAres::strerror(code) << llendl; +} + +LLAres::QueryResponder::~QueryResponder() +{ +} + +void LLAres::QueryResponder::queryResult(const char *buf, size_t len) +{ + llinfos << "LLAres::QueryResponder::queryResult not implemented" + << llendl; +} + +void LLAres::QueryResponder::queryError(int code) +{ + llinfos << "LLAres::QueryResponder::queryError " << code << ": " + << LLAres::strerror(code) << llendl; +} + +LLAres::LLAres() +{ + ares_init(&chan_); +} + +LLAres::~LLAres() +{ + ares_destroy(chan_); +} + +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) +{ + llinfos << "Rewriting " << uri << llendl; + + resp->mUri = LLURI(uri); + search("_" + resp->mUri.scheme() + "._tcp." + resp->mUri.hostName(), + RES_SRV, resp); +} + +LLQueryResponder::LLQueryResponder() + : LLAres::QueryResponder(), + mResult(ARES_ENODATA) +{ +} + +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: + llinfos << "LLQueryResponder::parseRR got unknown RR type " << rrtype + << llendl; + 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: + llinfos << "Cannot grok query type " << t << llendl; + 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() +{ + llinfos << "LLQueryResponder::queryResult not implemented" << llendl; +} + +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) +{ + llinfos << "LLAres::SrvResponder::srvResult not implemented" << llendl; + + for (size_t i = 0; i < ents.size(); i++) + { + const LLSrvRecord *s = (const LLSrvRecord *) ents[i].get(); + + llinfos << "[" << i << "] " << s->host() << ":" << s->port() + << " priority " << s->priority() + << " weight " << s->weight() + << llendl; + } +} + +void LLAres::SrvResponder::srvError(int code) +{ + llinfos << "LLAres::SrvResponder::srvError " << code << ": " + << LLAres::strerror(code) << llendl; +} + +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(); + } + + int socks[ARES_GETSOCK_MAXNUM]; + apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM]; + apr_int32_t nsds = 0; + apr_status_t status; + apr_pool_t *pool; + int nactive = 0; + int bitmask; + + bitmask = ares_getsock(chan_, socks, ARES_GETSOCK_MAXNUM); + + if (bitmask == 0) + { + goto bail; + } + + status = apr_pool_create(&pool, gAPRPoolp); + 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); + if (status != APR_SUCCESS) + { + ll_apr_warn_status(status); + goto bail_pool; + } + + aprFds[nactive].desc.s = aprSock; + aprFds[nactive].desc_type = APR_POLL_SOCKET; + aprFds[nactive].p = pool; + 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); + } + } + +bail_pool: + apr_pool_destroy(pool); + +bail: + 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; +} + +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) +{ +} + +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) +{ +} + +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) +{ + llinfos << "LLAres::UriRewriteResponder::rewriteResult not implemented" + << llendl; + + for (size_t i = 0; i < uris.size(); i++) + { + llinfos << "[" << i << "] " << uris[i] << llendl; + } +} diff --git a/indra/llmessage/llares.h b/indra/llmessage/llares.h new file mode 100644 index 0000000000..4dd65600cc --- /dev/null +++ b/indra/llmessage/llares.h @@ -0,0 +1,572 @@ +/** + * @file llares.h + * @author Bryan O'Sullivan + * @date 2007-08-15 + * @brief Wrapper for asynchronous DNS lookups. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLARES_H +#define LL_LLARES_H + +#ifdef LL_WINDOWS +# include <ws2tcpip.h> +#endif + +#ifdef LL_STANDALONE +# include <ares.h> +#else +# include <ares/ares.h> +#endif + +#include "llmemory.h" +#include "lluri.h" + +class LLQueryResponder; + +/** + * @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); + +protected: + ares_channel chan_; + +}; + +/** + * 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(); + +#endif // LL_LLARES_H diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp index 07a3655697..d561087ae4 100644 --- a/indra/llmessage/llfiltersd2xmlrpc.cpp +++ b/indra/llmessage/llfiltersd2xmlrpc.cpp @@ -81,7 +81,7 @@ #include <sstream> #include <iterator> #include <xmlrpc-epi/xmlrpc.h> -#include "apr-1/apr_base64.h" +#include "apr_base64.h" #include "llbuffer.h" #include "llbufferstream.h" diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h index e480f83b55..d8b34cbe44 100644 --- a/indra/llmessage/lliopipe.h +++ b/indra/llmessage/lliopipe.h @@ -36,7 +36,7 @@ #include <boost/intrusive_ptr.hpp> #include <boost/shared_ptr.hpp> -#include "apr-1/apr_poll.h" +#include "apr_poll.h" #include "llsd.h" diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index b1f55a297c..ff7c32aee8 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -68,7 +68,7 @@ bool is_addr_in_use(apr_status_t status) // Define this to see the actual file descriptors being tossed around. //#define LL_DEBUG_SOCKET_FILE_DESCRIPTORS 1 #if LL_DEBUG_SOCKET_FILE_DESCRIPTORS -#include "apr-1/apr_portable.h" +#include "apr_portable.h" #endif #endif diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h index 586f489b28..b6cf0f3e70 100644 --- a/indra/llmessage/lliosocket.h +++ b/indra/llmessage/lliosocket.h @@ -43,8 +43,8 @@ */ #include "lliopipe.h" -#include "apr-1/apr_pools.h" -#include "apr-1/apr_network_io.h" +#include "apr_pools.h" +#include "apr_network_io.h" #include "llchainio.h" class LLHost; diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp index ac0ee66e41..1a076b7281 100644 --- a/indra/llmessage/llmail.cpp +++ b/indra/llmessage/llmail.cpp @@ -42,10 +42,9 @@ #include <string> #include <sstream> -#include <boost/regex.hpp> -#include "apr-1/apr_pools.h" -#include "apr-1/apr_network_io.h" +#include "apr_pools.h" +#include "apr_network_io.h" #include "llapr.h" #include "llbase32.h" // IM-to-email address @@ -66,8 +65,6 @@ static apr_pool_t* gMailPool; static apr_sockaddr_t* gSockAddr; static apr_socket_t* gMailSocket; -// According to RFC2822 -static const boost::regex valid_subject_chars("[\\x1-\\x9\\xb\\xc\\xe-\\x7f]*"); bool connect_smtp(); void disconnect_smtp(); @@ -173,6 +170,22 @@ void LLMail::enable(bool mail_enabled) gMailEnabled = mail_enabled; } +// Test a subject line for RFC2822 compliance. +static bool valid_subject_chars(const char *subject) +{ + for (; *subject != '\0'; subject++) + { + unsigned char c = *subject; + + if (c == '\xa' || c == '\xd' || c > '\x7f') + { + return false; + } + } + + return true; +} + // static std::string LLMail::buildSMTPTransaction( const char* from_name, @@ -187,7 +200,7 @@ std::string LLMail::buildSMTPTransaction( << " from address." << llendl; return std::string(); } - if(! boost::regex_match(subject, valid_subject_chars)) + if(!valid_subject_chars(subject)) { llinfos << "send_mail build_smtp_transaction reject: bad subject header: " << "to=<" << to_address diff --git a/indra/llmessage/llmessagetemplateparser.cpp b/indra/llmessage/llmessagetemplateparser.cpp index e8843c7696..50f216ed6f 100644 --- a/indra/llmessage/llmessagetemplateparser.cpp +++ b/indra/llmessage/llmessagetemplateparser.cpp @@ -161,7 +161,7 @@ S32 get_checker_number(char checker) } // check token based on passed simplified regular expression -BOOL b_check_token(const char *token, char *regexp) +BOOL b_check_token(const char *token, const char *regexp) { S32 tptr, rptr = 0; S32 current_checker, next_checker = 0; diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index b87b66822c..503ca947df 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -36,7 +36,7 @@ #include <map> #include <set> -#include "apr-1/apr_poll.h" +#include "apr_poll.h" #include "llapr.h" #include "llmemtype.h" @@ -49,7 +49,7 @@ //#define LL_DEBUG_PIPE_TYPE_IN_PUMP 1 //#define LL_DEBUG_POLL_FILE_DESCRIPTORS 1 #if LL_DEBUG_POLL_FILE_DESCRIPTORS -#include "apr-1/apr_portable.h" +#include "apr_portable.h" #endif #endif @@ -261,7 +261,7 @@ bool LLPumpIO::addChain( bool LLPumpIO::setTimeoutSeconds(F32 timeout) { // If no chain is running, return failure. - if(current_chain_t() == mCurrentChain) + if(mRunningChains.end() == mCurrentChain) { return false; } @@ -365,7 +365,7 @@ S32 LLPumpIO::setLock() // lock the runner at the same time. // If no chain is running, return failure. - if(current_chain_t() == mCurrentChain) + if(mRunningChains.end() == mCurrentChain) { return 0; } @@ -414,7 +414,7 @@ bool LLPumpIO::sleepChain(F64 seconds) bool LLPumpIO::copyCurrentLinkInfo(links_t& links) const { LLMemType m1(LLMemType::MTYPE_IO_PUMP); - if(current_chain_t() == mCurrentChain) + if(mRunningChains.end() == mCurrentChain) { return false; } @@ -584,6 +584,7 @@ void LLPumpIO::pump(const S32& poll_timeout) } PUMP_DEBUG; mCurrentChain = run_chain; + if((*run_chain).mDescriptors.empty()) { // if there are no conditionals, just process this chain. @@ -702,7 +703,7 @@ void LLPumpIO::pump(const S32& poll_timeout) PUMP_DEBUG; // null out the chain - mCurrentChain = current_chain_t(); + mCurrentChain = mRunningChains.end(); END_PUMP_DEBUG; } diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h index 1609650f1f..fe7012ad6c 100644 --- a/indra/llmessage/llpumpio.h +++ b/indra/llmessage/llpumpio.h @@ -39,7 +39,7 @@ #include <sys/param.h> #endif -#include "apr-1/apr_pools.h" +#include "apr_pools.h" #include "llbuffer.h" #include "llframetimer.h" #include "lliopipe.h" diff --git a/indra/llmessage/llsdmessagereader.cpp b/indra/llmessage/llsdmessagereader.cpp index ad4e21efa9..4ca7895613 100755 --- a/indra/llmessage/llsdmessagereader.cpp +++ b/indra/llmessage/llsdmessagereader.cpp @@ -37,6 +37,13 @@ #include "llsdmessagebuilder.h" #include "llsdutil.h" +#include "v3math.h" +#include "v4math.h" +#include "v3dmath.h" +#include "v2math.h" +#include "llquaternion.h" +#include "v4color.h" + LLSDMessageReader::LLSDMessageReader() : mMessageName(NULL) { diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 87e1d4e50f..e7be235221 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -42,7 +42,7 @@ #include "llpumpio.h" #include "llsd.h" #include "llstring.h" -#include "apr-1/apr_env.h" +#include "apr_env.h" static const U32 HTTP_STATUS_PIPE_ERROR = 499; diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 04f61c53d7..c1731532ca 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -46,9 +46,9 @@ #include <sstream> #include "llapr.h" -#include "apr-1/apr_portable.h" -#include "apr-1/apr_network_io.h" -#include "apr-1/apr_poll.h" +#include "apr_portable.h" +#include "apr_network_io.h" +#include "apr_poll.h" // linden library headers #include "indra_constants.h" @@ -289,7 +289,8 @@ void LLMessageSystem::init() LLMessageSystem::LLMessageSystem(const char *filename, U32 port, S32 version_major, S32 version_minor, - S32 version_patch) + S32 version_patch, + bool failure_is_fatal) { init(); @@ -306,7 +307,7 @@ LLMessageSystem::LLMessageSystem(const char *filename, U32 port, mCircuitPrintFreq = 60.f; // seconds - loadTemplateFile(filename); + loadTemplateFile(filename, failure_is_fatal); mTemplateMessageBuilder = new LLTemplateMessageBuilder(mMessageTemplates); mLLSDMessageBuilder = new LLSDMessageBuilder(); @@ -365,7 +366,8 @@ LLMessageSystem::LLMessageSystem(const char *filename, U32 port, // Read file and build message templates -void LLMessageSystem::loadTemplateFile(const char* filename) +void LLMessageSystem::loadTemplateFile(const char* filename, + bool failure_is_fatal) { if(!filename) { @@ -377,7 +379,11 @@ void LLMessageSystem::loadTemplateFile(const char* filename) std::string template_body; if(!_read_file_into_string(template_body, filename)) { - LL_WARNS("Messaging") << "Failed to open template: " << filename << llendl; + if (failure_is_fatal) { + LL_ERRS("Messaging") << "Failed to open template: " << filename << llendl; + } else { + LL_WARNS("Messaging") << "Failed to open template: " << filename << llendl; + } mbError = TRUE; return; } @@ -2475,22 +2481,24 @@ void dump_prehash_files() } } -BOOL start_messaging_system( +bool start_messaging_system( const std::string& template_name, U32 port, S32 version_major, S32 version_minor, S32 version_patch, - BOOL b_dump_prehash_file, + bool b_dump_prehash_file, const std::string& secret, - const LLUseCircuitCodeResponder* responder) + const LLUseCircuitCodeResponder* responder, + bool failure_is_fatal) { gMessageSystem = new LLMessageSystem( template_name.c_str(), port, version_major, version_minor, - version_patch); + version_patch, + failure_is_fatal); g_shared_secret.assign(secret); if (!gMessageSystem) diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index 7d3c0e93ec..7462e1b1df 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -284,7 +284,8 @@ public: public: // Read file and build message templates LLMessageSystem(const char *filename, U32 port, S32 version_major, - S32 version_minor, S32 version_patch); + S32 version_minor, S32 version_patch, + bool failure_is_fatal = true); ~LLMessageSystem(); @@ -294,7 +295,7 @@ public: // Read file and build message templates filename must point to a // valid string which specifies the path of a valid linden // template. - void loadTemplateFile(const char* filename); + void loadTemplateFile(const char* filename, bool failure_is_fatal); // methods for building, sending, receiving, and handling messages @@ -764,16 +765,17 @@ extern LLMessageSystem *gMessageSystem; // Must specific overall system version, which is used to determine // if a patch is available in the message template checksum verification. -// Return TRUE if able to initialize system. -BOOL start_messaging_system( +// Return true if able to initialize system. +bool start_messaging_system( const std::string& template_name, U32 port, S32 version_major, S32 version_minor, S32 version_patch, - BOOL b_dump_prehash_file, + bool b_dump_prehash_file, const std::string& secret, - const LLUseCircuitCodeResponder* responder = NULL); + const LLUseCircuitCodeResponder* responder = NULL, + bool failure_is_fatal = true); void end_messaging_system(); |