Bug 1281482: Extend STUN rate limit to e10s sockets. r=drno

--HG--
extra : rebase_source : d39dec248379da239e0a3ed8bd904e713d2f1fa8
This commit is contained in:
Byron Campen [:bwc] 2016-09-22 10:38:06 -05:00
parent cc0747ceed
commit b571d6f4c1

View File

@ -743,6 +743,58 @@ abort:
return(_status);
}
static int ShouldDrop(size_t len) {
// Global rate limiting for stun requests, to mitigate the ice hammer DoS
// (see http://tools.ietf.org/html/draft-thomson-mmusic-ice-webrtc)
// Tolerate rate of 8k/sec, for one second.
static SimpleTokenBucket burst(16384*1, 16384);
// Tolerate rate of 7.2k/sec over twenty seconds.
static SimpleTokenBucket sustained(7372*20, 7372);
// Check number of tokens in each bucket.
if (burst.getTokens(UINT32_MAX) < len) {
r_log(LOG_GENERIC, LOG_ERR,
"Short term global rate limit for STUN requests exceeded.");
#ifdef MOZILLA_INTERNAL_API
nr_socket_short_term_violation_time = TimeStamp::Now();
#endif
// Bug 1013007
#if !EARLY_BETA_OR_EARLIER
return R_WOULDBLOCK;
#else
MOZ_ASSERT(false,
"Short term global rate limit for STUN requests exceeded. Go "
"bug bcampen@mozilla.com if you weren't intentionally "
"spamming ICE candidates, or don't know what that means.");
#endif
}
if (sustained.getTokens(UINT32_MAX) < len) {
r_log(LOG_GENERIC, LOG_ERR,
"Long term global rate limit for STUN requests exceeded.");
#ifdef MOZILLA_INTERNAL_API
nr_socket_long_term_violation_time = TimeStamp::Now();
#endif
// Bug 1013007
#if !EARLY_BETA_OR_EARLIER
return R_WOULDBLOCK;
#else
MOZ_ASSERT(false,
"Long term global rate limit for STUN requests exceeded. Go "
"bug bcampen@mozilla.com if you weren't intentionally "
"spamming ICE candidates, or don't know what that means.");
#endif
}
// Take len tokens from both buckets.
// (not threadsafe, but no problem since this is only called from STS)
burst.getTokens(len);
sustained.getTokens(len);
return 0;
}
// This should be called on the STS thread.
int NrSocket::sendto(const void *msg, size_t len,
int flags, nr_transport_addr *to) {
@ -757,55 +809,8 @@ int NrSocket::sendto(const void *msg, size_t len,
if(fd_==nullptr)
ABORT(R_EOD);
if (nr_is_stun_request_message((UCHAR*)msg, len)) {
// Global rate limiting for stun requests, to mitigate the ice hammer DoS
// (see http://tools.ietf.org/html/draft-thomson-mmusic-ice-webrtc)
// Tolerate rate of 8k/sec, for one second.
static SimpleTokenBucket burst(16384*1, 16384);
// Tolerate rate of 7.2k/sec over twenty seconds.
static SimpleTokenBucket sustained(7372*20, 7372);
// Check number of tokens in each bucket.
if (burst.getTokens(UINT32_MAX) < len) {
r_log(LOG_GENERIC, LOG_ERR,
"Short term global rate limit for STUN requests exceeded.");
#ifdef MOZILLA_INTERNAL_API
nr_socket_short_term_violation_time = TimeStamp::Now();
#endif
// Bug 1013007
#if !EARLY_BETA_OR_EARLIER
ABORT(R_WOULDBLOCK);
#else
MOZ_ASSERT(false,
"Short term global rate limit for STUN requests exceeded. Go "
"bug bcampen@mozilla.com if you weren't intentionally "
"spamming ICE candidates, or don't know what that means.");
#endif
}
if (sustained.getTokens(UINT32_MAX) < len) {
r_log(LOG_GENERIC, LOG_ERR,
"Long term global rate limit for STUN requests exceeded.");
#ifdef MOZILLA_INTERNAL_API
nr_socket_long_term_violation_time = TimeStamp::Now();
#endif
// Bug 1013007
#if !EARLY_BETA_OR_EARLIER
ABORT(R_WOULDBLOCK);
#else
MOZ_ASSERT(false,
"Long term global rate limit for STUN requests exceeded. Go "
"bug bcampen@mozilla.com if you weren't intentionally "
"spamming ICE candidates, or don't know what that means.");
#endif
}
// Take len tokens from both buckets.
// (not threadsafe, but no problem since this is only called from STS)
burst.getTokens(len);
sustained.getTokens(len);
if (nr_is_stun_request_message((UCHAR*)msg, len) && ShouldDrop(len)) {
ABORT(R_WOULDBLOCK);
}
// TODO: Convert flags?
@ -1363,6 +1368,10 @@ int NrUdpSocketIpc::sendto(const void *msg, size_t len, int flags,
return r;
}
if (nr_is_stun_request_message((UCHAR*)msg, len) && ShouldDrop(len)) {
return R_WOULDBLOCK;
}
nsAutoPtr<DataBuffer> buf(new DataBuffer(static_cast<const uint8_t*>(msg), len));
RUN_ON_THREAD(io_thread_,