summaryrefslogtreecommitdiff
path: root/indra/llmessage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage')
-rw-r--r--indra/llmessage/llcircuit.cpp11
-rw-r--r--indra/llmessage/llcircuit.h7
-rw-r--r--indra/llmessage/llmail.cpp36
-rw-r--r--indra/llmessage/llmail.h61
-rw-r--r--indra/llmessage/llmessagetemplate.cpp20
-rw-r--r--indra/llmessage/llmessagetemplate.h8
-rw-r--r--indra/llmessage/llmessagetemplateparser.cpp4
-rw-r--r--indra/llmessage/lltemplatemessagereader.cpp5
-rw-r--r--indra/llmessage/lltemplatemessagereader.h2
-rw-r--r--indra/llmessage/message.cpp25
-rw-r--r--indra/llmessage/message.h3
11 files changed, 150 insertions, 32 deletions
diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp
index 431fe802f6..9ad84d8242 100644
--- a/indra/llmessage/llcircuit.cpp
+++ b/indra/llmessage/llcircuit.cpp
@@ -60,6 +60,7 @@
#include "llrand.h"
#include "llstl.h"
#include "lltransfermanager.h"
+#include "llmodularmath.h"
const F32 PING_INTERVAL = 5.f; // seconds
const S32 PING_START_BLOCK = 3; // How many pings behind we have to be to consider ourself blocked.
@@ -676,6 +677,8 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
mPacketsIn++;
setPacketInID((id + 1) % LL_MAX_OUT_PACKET_ID);
+ mLastPacketGap = 0;
+ mOutOfOrderRate.count(0);
return;
}
@@ -683,6 +686,7 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
// now, check to see if we've got a gap
+ U32 gap = 0;
if ((mPacketsInID == id))
{
// nope! bump and wrap the counter, then return
@@ -704,6 +708,11 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
// otherwise, walk from mCurrentCircuit->mPacketsInID to id with wrapping, adding the values to the map
// and setting mPacketsInID to id + 1 % LL_MAX_OUT_PACKET_ID
+ // babbage: all operands in expression are unsigned, so modular
+ // arithmetic will always find correct gap, regardless of wrap arounds.
+ const U8 width = 24;
+ gap = LLModularMath::subtract<width>(mPacketsInID, id);
+
if (mPotentialLostPackets.find(id) != mPotentialLostPackets.end())
{
if(gMessageSystem->mVerboseLog)
@@ -765,6 +774,8 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
}
}
+ mOutOfOrderRate.count(gap);
+ mLastPacketGap = gap;
}
diff --git a/indra/llmessage/llcircuit.h b/indra/llmessage/llcircuit.h
index 8824e6825a..492313da93 100644
--- a/indra/llmessage/llcircuit.h
+++ b/indra/llmessage/llcircuit.h
@@ -45,6 +45,7 @@
#include "llpacketack.h"
#include "lluuid.h"
#include "llthrottle.h"
+#include "llstat.h"
//
// Constants
@@ -133,6 +134,10 @@ public:
S32 getUnackedPacketCount() const { return mUnackedPacketCount; }
S32 getUnackedPacketBytes() const { return mUnackedPacketBytes; }
F64 getNextPingSendTime() const { return mNextPingSendTime; }
+ F32 getOutOfOrderRate(LLStatAccum::TimeScale scale = LLStatAccum::SCALE_MINUTE)
+ { return mOutOfOrderRate.meanValue(scale); }
+ U32 getLastPacketGap() const { return mLastPacketGap; }
+ LLHost getHost() const { return mHost; }
LLThrottleGroup &getThrottleGroup() { return mThrottles; }
@@ -276,6 +281,8 @@ protected:
LLTimer mExistenceTimer; // initialized when circuit created, used to track bandwidth numbers
S32 mCurrentResendCount; // Number of resent packets since last spam
+ LLStatRate mOutOfOrderRate; // Rate of out of order packets coming in.
+ U32 mLastPacketGap; // Gap in sequence number of last packet.
};
diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp
index 6a8931cf73..82e477884b 100644
--- a/indra/llmessage/llmail.cpp
+++ b/indra/llmessage/llmail.cpp
@@ -51,6 +51,7 @@
#include "llblowfishcipher.h"
#include "llerror.h"
#include "llhost.h"
+#include "llsd.h"
#include "llstring.h"
#include "lluuid.h"
#include "net.h"
@@ -111,16 +112,22 @@ void disconnect_smtp()
// Returns TRUE on success.
// message should NOT be SMTP escaped.
// static
-BOOL LLMail::send(const char* from_name, const char* from_address,
- const char* to_name, const char* to_address,
- const char* subject, const char* message)
+BOOL LLMail::send(
+ const char* from_name,
+ const char* from_address,
+ const char* to_name,
+ const char* to_address,
+ const char* subject,
+ const char* message,
+ const LLSD& headers)
{
std::string header = buildSMTPTransaction(
from_name,
from_address,
to_name,
to_address,
- subject);
+ subject,
+ headers);
if(header.empty())
{
return FALSE;
@@ -192,7 +199,8 @@ std::string LLMail::buildSMTPTransaction(
const char* from_address,
const char* to_name,
const char* to_address,
- const char* subject)
+ const char* subject,
+ const LLSD& headers)
{
if(!from_address || !to_address)
{
@@ -236,8 +244,20 @@ std::string LLMail::buildSMTPTransaction(
<< "DATA\r\n"
<< "From: " << from_fmt.str() << "\r\n"
<< "To: " << to_fmt.str() << "\r\n"
- << "Subject: " << subject << "\r\n"
- << "\r\n";
+ << "Subject: " << subject << "\r\n";
+
+ if(headers.isMap())
+ {
+ LLSD::map_const_iterator iter = headers.beginMap();
+ LLSD::map_const_iterator end = headers.endMap();
+ for(; iter != end; ++iter)
+ {
+ header << (*iter).first << ": " << ((*iter).second).asString()
+ << "\r\n";
+ }
+ }
+
+ header << "\r\n";
return header.str();
}
@@ -324,7 +344,7 @@ bool LLMail::send(
<< "when sending messages larger than " << LL_MAX_KNOWN_GOOD_MAIL_SIZE
<< " bytes. The next log about success is potentially a lie." << llendl;
}
- llinfos << "send_mail success: "
+ lldebugs << "send_mail success: "
<< "to=<" << to_address
<< ">, from=<" << from_address << ">"
<< ", bytes=" << original_size
diff --git a/indra/llmessage/llmail.h b/indra/llmessage/llmail.h
index 2a88592b89..0329602e0b 100644
--- a/indra/llmessage/llmail.h
+++ b/indra/llmessage/llmail.h
@@ -34,7 +34,7 @@
typedef struct apr_pool_t apr_pool_t;
-class LLUUID;
+#include "llsd.h"
class LLMail
{
@@ -45,34 +45,51 @@ public:
// Allow all email transmission to be disabled/enabled.
static void enable(bool mail_enabled);
- // returns TRUE if the call succeeds, FALSE otherwise.
- //
- // Results in:
- // From: "from_name" <from_address>
- // To: "to_name" <to_address>
- // Subject: subject
- // message
- static BOOL send(const char* from_name, const char* from_address,
- const char* to_name, const char* to_address,
- const char* subject, const char* message);
+ /**
+ * @brief send an email
+ * @param from_name The name of the email sender
+ * @param from_address The email address for the sender
+ * @param to_name The name of the email recipient
+ * @param to_address The email recipient address
+ * @param subject The subject of the email
+ * @param headers optional X-Foo headers in an llsd map.
+ * @return Returns TRUE if the call succeeds, FALSE otherwise.
+ *
+ * Results in:
+ * From: "from_name" <from_address>
+ * To: "to_name" <to_address>
+ * Subject: subject
+ *
+ * message
+ */
+ static BOOL send(
+ const char* from_name,
+ const char* from_address,
+ const char* to_name,
+ const char* to_address,
+ const char* subject,
+ const char* message,
+ const LLSD& headers = LLSD());
/**
- * @brief build the complete smtp transaction & header for use in an
- * mail.
- *
- * @param from_name The name of the email sender
- * @param from_address The email address for the sender
- * @param to_name The name of the email recipient
- * @param to_name The email recipient address
- * @param subject The subject of the email
- * @return Returns the complete SMTP transaction mail header.
- */
+ * @brief build the complete smtp transaction & header for use in an
+ * mail.
+ *
+ * @param from_name The name of the email sender
+ * @param from_address The email address for the sender
+ * @param to_name The name of the email recipient
+ * @param to_address The email recipient address
+ * @param subject The subject of the email
+ * @param headers optional X-Foo headers in an llsd map.
+ * @return Returns the complete SMTP transaction mail header.
+ */
static std::string buildSMTPTransaction(
const char* from_name,
const char* from_address,
const char* to_name,
const char* to_address,
- const char* subject);
+ const char* subject,
+ const LLSD& headers = LLSD());
/**
* @brief send an email with header and body.
diff --git a/indra/llmessage/llmessagetemplate.cpp b/indra/llmessage/llmessagetemplate.cpp
index c09f3e9c49..78085f40af 100644
--- a/indra/llmessage/llmessagetemplate.cpp
+++ b/indra/llmessage/llmessagetemplate.cpp
@@ -175,3 +175,23 @@ std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg)
return s;
}
+
+void LLMessageTemplate::banUdp()
+{
+ static const char* deprecation[] = {
+ "NotDeprecated",
+ "Deprecated",
+ "UDPDeprecated",
+ "UDPBlackListed"
+ };
+ if (mDeprecation != MD_DEPRECATED)
+ {
+ llinfos << "Setting " << mName << " to UDPBlackListed was " << deprecation[mDeprecation] << llendl;
+ mDeprecation = MD_UDPBLACKLISTED;
+ }
+ else
+ {
+ llinfos << mName << " is already more deprecated than UDPBlackListed" << llendl;
+ }
+}
+
diff --git a/indra/llmessage/llmessagetemplate.h b/indra/llmessage/llmessagetemplate.h
index 85fb0a7782..82421b1f5a 100644
--- a/indra/llmessage/llmessagetemplate.h
+++ b/indra/llmessage/llmessagetemplate.h
@@ -265,6 +265,7 @@ enum EMsgDeprecation
{
MD_NOTDEPRECATED,
MD_UDPDEPRECATED,
+ MD_UDPBLACKLISTED,
MD_DEPRECATED
};
@@ -375,6 +376,13 @@ public:
return FALSE;
}
+ bool isUdpBanned() const
+ {
+ return mDeprecation == MD_UDPBLACKLISTED;
+ }
+
+ void banUdp();
+
bool isBanned(bool trustedSource) const
{
return trustedSource ? mBanFromTrusted : mBanFromUntrusted;
diff --git a/indra/llmessage/llmessagetemplateparser.cpp b/indra/llmessage/llmessagetemplateparser.cpp
index 50f216ed6f..86662c5342 100644
--- a/indra/llmessage/llmessagetemplateparser.cpp
+++ b/indra/llmessage/llmessagetemplateparser.cpp
@@ -525,6 +525,10 @@ LLMessageTemplate * LLTemplateParser::parseMessage(LLTemplateTokenizer & tokens)
{
templatep->setDeprecation(MD_UDPDEPRECATED);
}
+ else if (tokens.want("UDPBlackListed"))
+ {
+ templatep->setDeprecation(MD_UDPBLACKLISTED);
+ }
else if (tokens.want("NotDeprecated"))
{
// this is the default value, but it can't hurt to set it twice
diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp
index b5186ad539..822051d363 100644
--- a/indra/llmessage/lltemplatemessagereader.cpp
+++ b/indra/llmessage/lltemplatemessagereader.cpp
@@ -797,6 +797,11 @@ bool LLTemplateMessageReader::isBanned(bool trustedSource) const
return mCurrentRMessageTemplate->isBanned(trustedSource);
}
+bool LLTemplateMessageReader::isUdpBanned() const
+{
+ return mCurrentRMessageTemplate->isUdpBanned();
+}
+
//virtual
void LLTemplateMessageReader::copyToBuilder(LLMessageBuilder& builder) const
{
diff --git a/indra/llmessage/lltemplatemessagereader.h b/indra/llmessage/lltemplatemessagereader.h
index ea3ec9a3d8..268afa3ef6 100644
--- a/indra/llmessage/lltemplatemessagereader.h
+++ b/indra/llmessage/lltemplatemessagereader.h
@@ -109,7 +109,7 @@ public:
bool isTrusted() const;
bool isBanned(bool trusted_source) const;
-
+ bool isUdpBanned() const;
private:
void getData(const char *blockname, const char *varname, void *datap,
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index 290682f7ce..abd9467602 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -754,7 +754,15 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
clearReceiveState();
valid_packet = FALSE;
}
-
+ if( valid_packet && mTemplateMessageReader->isUdpBanned())
+ {
+ llwarns << "Received UDP black listed message "
+ << mTemplateMessageReader->getMessageName()
+ << " from " << host << llendl;
+ clearReceiveState();
+ valid_packet = FALSE;
+ }
+
if( valid_packet )
{
logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) );
@@ -4013,3 +4021,18 @@ bool LLMessageSystem::checkAllMessages(S64 frame_count, LLPumpIO* http_pump)
http_pump->callback();
return (mPacketsIn - packetsIn) > 0;
}
+
+void LLMessageSystem::banUdpMessage(const std::string& name)
+{
+ message_template_name_map_t::iterator itt = mMessageTemplates.find(
+ LLMessageStringTable::getInstance()->getString(name.c_str())
+ );
+ if(itt != mMessageTemplates.end())
+ {
+ itt->second->banUdp();
+ }
+ else
+ {
+ llwarns << "Attempted to ban an unknown message: " << name << "." << llendl;
+ }
+}
diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
index e2d2ed46e2..f4f3927f66 100644
--- a/indra/llmessage/message.h
+++ b/indra/llmessage/message.h
@@ -562,6 +562,9 @@ public:
/** Return false true if name is unknown or trusted */
bool isUntrustedMessage(const std::string& name) const;
+ // Change this message to be UDP black listed.
+ void banUdpMessage(const std::string& name);
+
private:
// A list of the circuits that need to be sent DenyTrustedCircuit messages.
typedef std::set<LLHost> host_set_t;