You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2018/08/15 23:36:55 UTC

[mesos] 03/04: Fixed an authentication request amplification issue in the master.

This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch 1.7.x
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 7b44aba601a7ac87aaa7c37dad288a5db47f7906
Author: Benjamin Mahler <bm...@apache.org>
AuthorDate: Fri Aug 10 17:14:05 2018 -0700

    Fixed an authentication request amplification issue in the master.
    
    Per MESOS-9144, re-enqueuing authentication requests leads to an
    amplification effect which can overwhelm the master if requests
    continue to arrive rapidly on a heavily loaded master. This patch
    avoids the re-enqueing and ensures the master immediately processes
    a new authentication request for a client.
    
    Review: https://reviews.apache.org/r/68306
---
 src/master/master.cpp | 36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/src/master/master.cpp b/src/master/master.cpp
index 17bd283..ad83be2 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -9563,7 +9563,7 @@ void Master::authenticate(const UPID& from, const UPID& pid)
   //       about this discrepancy via ping messages so that it can
   //       reregister.
 
-  authenticated.erase(pid);
+  bool erased = authenticated.erase(pid) > 0;
 
   if (authenticator.isNone()) {
     // The default authenticator is CRAM-MD5 rather than none.
@@ -9586,30 +9586,28 @@ void Master::authenticate(const UPID& from, const UPID& pid)
     return;
   }
 
+  // If a new authentication is occurring for a client that already
+  // has an authentication in progress, we discard the old one
+  // (since the client is no longer interested in it) and
+  // immediately proceed with the new authentication.
   if (authenticating.contains(pid)) {
-    LOG(INFO) << "Queuing up authentication request from " << pid
-              << " because authentication is still in progress";
-
-    // Try to cancel the in progress authentication by discarding the
-    // future.
-    authenticating[pid].discard();
-
-    // Retry after the current authenticator session finishes.
-    authenticating[pid]
-      .onAny(defer(self(), &Self::authenticate, from, pid));
+    authenticating.at(pid).discard();
+    authenticating.erase(pid);
 
-    return;
+    LOG(INFO) << "Re-authenticating " << pid << ";"
+              << " discarding outstanding authentication";
+  } else {
+    LOG(INFO) << "Authenticating " << pid
+              << (erased ? "; clearing previous authentication" : "");
   }
 
-  LOG(INFO) << "Authenticating " << pid;
-
   // Start authentication.
   const Future<Option<string>> future = authenticator.get()->authenticate(from);
 
   // Save our state.
   authenticating[pid] = future;
 
-  future.onAny(defer(self(), &Self::_authenticate, pid, lambda::_1));
+  future.onAny(defer(self(), &Self::_authenticate, pid, future));
 
   // Don't wait for authentication to complete forever.
   delay(flags.authentication_v0_timeout,
@@ -9623,6 +9621,13 @@ void Master::_authenticate(
     const UPID& pid,
     const Future<Option<string>>& future)
 {
+  // Ignore stale authentication results (if the authentication
+  // future has been overwritten).
+  if (authenticating.get(pid) != future) {
+    LOG(INFO) << "Ignoring stale authentication result of " << pid;
+    return;
+  }
+
   if (future.isReady() && future->isSome()) {
     LOG(INFO) << "Successfully authenticated principal '" << future->get()
               << "' at " << pid;
@@ -9638,7 +9643,6 @@ void Master::_authenticate(
     LOG(INFO) << "Authentication of " << pid << " was discarded";
   }
 
-  CHECK(authenticating.contains(pid));
   authenticating.erase(pid);
 }