summaryrefslogtreecommitdiff
path: root/indra/llmessage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage')
-rw-r--r--indra/llmessage/CMakeLists.txt191
-rw-r--r--indra/llmessage/llares.cpp804
-rw-r--r--indra/llmessage/llares.h572
-rw-r--r--indra/llmessage/llfiltersd2xmlrpc.cpp2
-rw-r--r--indra/llmessage/lliopipe.h2
-rw-r--r--indra/llmessage/lliosocket.cpp2
-rw-r--r--indra/llmessage/lliosocket.h4
-rw-r--r--indra/llmessage/llmail.cpp25
-rw-r--r--indra/llmessage/llmessagetemplateparser.cpp2
-rw-r--r--indra/llmessage/llpumpio.cpp13
-rw-r--r--indra/llmessage/llpumpio.h2
-rwxr-xr-xindra/llmessage/llsdmessagereader.cpp7
-rw-r--r--indra/llmessage/llurlrequest.cpp2
-rw-r--r--indra/llmessage/message.cpp30
-rw-r--r--indra/llmessage/message.h14
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();