| 1542 | |
| 1543 | |
| 1544 | void Slave::authenticate(Duration minTimeout, Duration maxTimeout) |
| 1545 | { |
| 1546 | authenticated = false; |
| 1547 | |
| 1548 | if (master.isNone()) { |
| 1549 | return; |
| 1550 | } |
| 1551 | |
| 1552 | if (authenticating.isSome()) { |
| 1553 | // Authentication is in progress. Try to cancel it. |
| 1554 | // Note that it is possible that 'authenticating' is ready |
| 1555 | // and the dispatch to '_authenticate' is enqueued when we |
| 1556 | // are here, making the 'discard' here a no-op. This is ok |
| 1557 | // because we set 'reauthenticate' here which enforces a retry |
| 1558 | // in '_authenticate'. |
| 1559 | Future<bool> authenticating_ = authenticating.get(); |
| 1560 | authenticating_.discard(); |
| 1561 | reauthenticate = true; |
| 1562 | return; |
| 1563 | } |
| 1564 | |
| 1565 | LOG(INFO) << "Authenticating with master " << master.get(); |
| 1566 | |
| 1567 | // Ensure there is a link to the master before we start |
| 1568 | // communicating with it. |
| 1569 | link(master.get()); |
| 1570 | |
| 1571 | CHECK(authenticatee == nullptr); |
| 1572 | |
| 1573 | if (authenticateeName == DEFAULT_AUTHENTICATEE) { |
| 1574 | LOG(INFO) << "Using default CRAM-MD5 authenticatee"; |
| 1575 | authenticatee = new cram_md5::CRAMMD5Authenticatee(); |
| 1576 | } |
| 1577 | |
| 1578 | if (authenticatee == nullptr) { |
| 1579 | Try<Authenticatee*> module = |
| 1580 | modules::ModuleManager::create<Authenticatee>(authenticateeName); |
| 1581 | if (module.isError()) { |
| 1582 | EXIT(EXIT_FAILURE) |
| 1583 | << "Could not create authenticatee module '" |
| 1584 | << authenticateeName << "': " << module.error(); |
| 1585 | } |
| 1586 | LOG(INFO) << "Using '" << authenticateeName << "' authenticatee"; |
| 1587 | authenticatee = module.get(); |
| 1588 | } |
| 1589 | |
| 1590 | CHECK_SOME(credential); |
| 1591 | |
| 1592 | // We pick a random duration between `minTimeout` and `maxTimeout`. |
| 1593 | Duration timeout = |
| 1594 | minTimeout + (maxTimeout - minTimeout) * ((double)os::random() / RAND_MAX); |
| 1595 | |
| 1596 | authenticating = |
| 1597 | authenticatee->authenticate(master.get(), self(), credential.get()) |
| 1598 | .onAny(defer(self(), &Self::_authenticate, minTimeout, maxTimeout)) |
| 1599 | .after(timeout, [](Future<bool> future) { |
| 1600 | // NOTE: Discarded future results in a retry in '_authenticate()'. |
| 1601 | // This is a no-op if the future is already ready. |