示例#1
0
bool isSelf(const HostAndPort& hostAndPort, ServiceContext* const ctx) {
    // Fastpath: check if the host&port in question is bound to one
    // of the interfaces on this machine.
    // No need for ip match if the ports do not match
    if (hostAndPort.port() == serverGlobalParams.port) {
        std::vector<std::string> myAddrs = serverGlobalParams.bind_ips;

        // If any of the bound addresses is the default route (0.0.0.0 on IPv4) it means we are
        // listening on all network interfaces and need to check against any of them.
        if (myAddrs.empty() ||
            std::any_of(myAddrs.cbegin(), myAddrs.cend(), [](std::string const& addrStr) {
                return HostAndPort(addrStr, serverGlobalParams.port).isDefaultRoute();
            })) {
            myAddrs = getBoundAddrs(IPv6Enabled());
        }

        const std::vector<std::string> hostAddrs =
            getAddrsForHost(hostAndPort.host(), hostAndPort.port(), IPv6Enabled());

        for (std::vector<std::string>::const_iterator i = myAddrs.begin(); i != myAddrs.end();
             ++i) {
            for (std::vector<std::string>::const_iterator j = hostAddrs.begin();
                 j != hostAddrs.end();
                 ++j) {
                if (*i == *j) {
                    return true;
                }
            }
        }
    }

    ctx->waitForStartupComplete();

    try {
        DBClientConnection conn;
        conn.setSoTimeout(30);  // 30 second timeout

        // We need to avoid the isMaster call triggered by a normal connect, which would
        // cause a deadlock. 'isSelf' is called by the Replication Coordinator when validating
        // a replica set configuration document, but the 'isMaster' command requires a lock on the
        // replication coordinator to execute. As such we call we call 'connectSocketOnly', which
        // does not call 'isMaster'.
        if (!conn.connectSocketOnly(hostAndPort).isOK()) {
            return false;
        }

        if (auth::isInternalAuthSet() && !conn.authenticateInternalUser().isOK()) {
            return false;
        }
        BSONObj out;
        bool ok = conn.simpleCommand("admin", &out, "_isSelf");
        bool me = ok && out["id"].type() == jstOID && instanceId == out["id"].OID();

        return me;
    } catch (const std::exception& e) {
        warning() << "couldn't check isSelf (" << hostAndPort << ") " << e.what() << std::endl;
    }

    return false;
}
示例#2
0
bool isSelf(const HostAndPort& hostAndPort) {
    // Fastpath: check if the host&port in question is bound to one
    // of the interfaces on this machine.
    // No need for ip match if the ports do not match
    if (hostAndPort.port() == serverGlobalParams.port) {
        std::vector<std::string> myAddrs = serverGlobalParams.bind_ip.empty()
            ? getBoundAddrs(IPv6Enabled())
            : std::vector<std::string>();

        if (!serverGlobalParams.bind_ip.empty()) {
            boost::split(myAddrs, serverGlobalParams.bind_ip, boost::is_any_of(", "));
        }

        const std::vector<std::string> hostAddrs =
            getAddrsForHost(hostAndPort.host(), hostAndPort.port(), IPv6Enabled());

        for (std::vector<std::string>::const_iterator i = myAddrs.begin(); i != myAddrs.end();
             ++i) {
            for (std::vector<std::string>::const_iterator j = hostAddrs.begin();
                 j != hostAddrs.end();
                 ++j) {
                if (*i == *j) {
                    return true;
                }
            }
        }
    }

    // Ensure that the server is up and ready to accept incoming network requests.
    const Listener* listener = Listener::getTimeTracker();
    if (!listener) {
        return false;
    }
    listener->waitUntilListening();

    try {
        DBClientConnection conn;
        conn.setSoTimeout(30);  // 30 second timeout

        // We need to avoid the isMaster call triggered by a normal connect, which would
        // cause a deadlock. 'isSelf' is called by the Replication Coordinator when validating
        // a replica set configuration document, but the 'isMaster' command requires a lock on the
        // replication coordinator to execute. As such we call we call 'connectSocketOnly', which
        // does not call 'isMaster'.
        if (!conn.connectSocketOnly(hostAndPort).isOK()) {
            return false;
        }

        if (getGlobalAuthorizationManager()->isAuthEnabled() && isInternalAuthSet()) {
            if (!conn.authenticateInternalUser()) {
                return false;
            }
        }
        BSONObj out;
        bool ok = conn.simpleCommand("admin", &out, "_isSelf");
        bool me = ok && out["id"].type() == jstOID && instanceId == out["id"].OID();

        return me;
    } catch (const std::exception& e) {
        warning() << "couldn't check isSelf (" << hostAndPort << ") " << e.what() << std::endl;
    }

    return false;
}