diff options
author | Billy Donahue <billy.donahue@mongodb.com> | 2017-11-15 14:10:29 -0500 |
---|---|---|
committer | Billy Donahue <billy.donahue@mongodb.com> | 2017-11-15 14:10:29 -0500 |
commit | c748c45d62048c93f9fb4764662b5e2d22d241ad (patch) | |
tree | 25415f406847a9106b63125dceb01d5768b6e8c7 | |
parent | a784a196d212faded16bd8d11fa1f9368d4e60b0 (diff) | |
download | mongo-c748c45d62048c93f9fb4764662b5e2d22d241ad.tar.gz |
Revert "SERVER-31808 Query vector<SockAddr> from TransportLayer"
This reverts commit d641ef7968a26a3b84de584faff7437caef748b9.
-rw-r--r-- | jstests/replsets/localhost3.js | 11 | ||||
-rw-r--r-- | src/mongo/db/repl/repl_set_commands.cpp | 60 | ||||
-rw-r--r-- | src/mongo/shell/servers.js | 2 | ||||
-rw-r--r-- | src/mongo/transport/service_entry_point_test_suite.h | 4 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer.h | 2 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_asio.cpp | 13 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_asio.h | 4 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_legacy.cpp | 8 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_legacy.h | 2 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_manager.cpp | 9 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_manager.h | 2 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_mock.h | 2 | ||||
-rw-r--r-- | src/mongo/util/net/listen.cpp | 59 | ||||
-rw-r--r-- | src/mongo/util/net/listen.h | 16 |
14 files changed, 77 insertions, 117 deletions
diff --git a/jstests/replsets/localhost3.js b/jstests/replsets/localhost3.js deleted file mode 100644 index 66fbcf26151..00000000000 --- a/jstests/replsets/localhost3.js +++ /dev/null @@ -1,11 +0,0 @@ -// Test ReplSet default initiate with localhost-only binding - -(function() { - 'use strict'; - const rt = - new ReplSetTest({name: "foo", nodes: [MongoRunner.mongoOptions({bind_ip: undefined})]}); - const primary = rt.startSet({})[0]; - const db = primary.getDB('admin'); - const resp = assert.commandWorked(db.adminCommand({replSetInitiate: undefined})); - rt.stopSet(); -})(); diff --git a/src/mongo/db/repl/repl_set_commands.cpp b/src/mongo/db/repl/repl_set_commands.cpp index aca660cf80c..76873a1dd9b 100644 --- a/src/mongo/db/repl/repl_set_commands.cpp +++ b/src/mongo/db/repl/repl_set_commands.cpp @@ -249,6 +249,46 @@ private: } cmdReplSetGetConfig; namespace { +HostAndPort someHostAndPortForMe() { + const auto& bind_ip = serverGlobalParams.bind_ip; + const auto& bind_port = serverGlobalParams.port; + const auto& af = IPv6Enabled() ? AF_UNSPEC : AF_INET; + bool localhost_only = true; + + std::vector<std::string> addrs; + boost::split(addrs, bind_ip, boost::is_any_of(","), boost::token_compress_on); + for (const auto& addr : addrs) { + // Get all addresses associated with each named bind host. + // If we find any that are valid external identifiers, + // then go ahead and use the first one. + const auto& socks = SockAddr::createAll(addr, bind_port, af); + for (const auto& sock : socks) { + if (!sock.isLocalHost()) { + if (!sock.isDefaultRoute()) { + // Return the hostname as passed rather than the resolved address. + return HostAndPort(addr, bind_port); + } + localhost_only = false; + } + } + } + + if (localhost_only) { + // We're only binding localhost-type interfaces. + // Use one of those by name if available, + // otherwise fall back on "localhost". + return HostAndPort(addrs.size() ? addrs[0] : "localhost", bind_port); + } + + // Based on the above logic, this is only reached for --bind_ip '0.0.0.0'. + // We are listening externally, but we don't have a definite hostname. + // Ask the OS. + std::string h = getHostName(); + verify(!h.empty()); + verify(h != "localhost"); + return HostAndPort(h, serverGlobalParams.port); +} + void parseReplSetSeedList(ReplicationCoordinatorExternalState* externalState, const std::string& replSetString, std::string* setname, @@ -341,12 +381,9 @@ public: b.append("_id", name); b.append("version", 1); BSONObjBuilder members; - StatusWith<HostAndPort> me = _someHostAndPortForMe(opCtx); - if (!me.isOK()) { - return appendCommandStatus(result, me.getStatus()); - } - members.append("0", BSON("_id" << 0 << "host" << me.getValue().toString())); - result.append("me", me.getValue().toString()); + HostAndPort me = someHostAndPortForMe(); + members.append("0", BSON("_id" << 0 << "host" << me.toString())); + result.append("me", me.toString()); for (unsigned i = 0; i < seeds.size(); i++) { members.append(BSONObjBuilder::numStr(i + 1), BSON("_id" << i + 1 << "host" << seeds[i].toString())); @@ -369,17 +406,6 @@ public: } private: - static StatusWith<HostAndPort> _someHostAndPortForMe(OperationContext* opCtx) { - auto service = opCtx->getServiceContext(); - auto transportLayer = service->getTransportLayer(); - invariant(transportLayer != nullptr); - std::vector<HostAndPort> acceptPorts = transportLayer->getListeningPorts(); - if (acceptPorts.empty()) { - return Status(ErrorCodes::InternalError, "not listening on any ports"); - } - return acceptPorts.front(); - } - ActionSet getAuthActionSet() const override { return ActionSet{ActionType::replSetConfigure}; } diff --git a/src/mongo/shell/servers.js b/src/mongo/shell/servers.js index beb64a68e03..19f00f5e2db 100644 --- a/src/mongo/shell/servers.js +++ b/src/mongo/shell/servers.js @@ -473,7 +473,7 @@ var MongoRunner, _startMongod, startMongoProgram, runMongoProgram, startMongoPro opts.networkMessageCompressors = jsTestOptions().networkMessageCompressors; } - if (!opts.hasOwnProperty('bind_ip')) { + if (!opts.bind_ip) { opts.bind_ip = "0.0.0.0"; } diff --git a/src/mongo/transport/service_entry_point_test_suite.h b/src/mongo/transport/service_entry_point_test_suite.h index c2670139a6a..96461584b83 100644 --- a/src/mongo/transport/service_entry_point_test_suite.h +++ b/src/mongo/transport/service_entry_point_test_suite.h @@ -115,10 +115,6 @@ public: Status start() override; void shutdown() override; - std::vector<HostAndPort> getListeningPorts() const override { - return {}; - } - transport::MockTicket* getMockTicket(const transport::Ticket& ticket); // Mocked method hooks diff --git a/src/mongo/transport/transport_layer.h b/src/mongo/transport/transport_layer.h index cc305cd0e19..383e3bd0cd5 100644 --- a/src/mongo/transport/transport_layer.h +++ b/src/mongo/transport/transport_layer.h @@ -158,8 +158,6 @@ public: */ virtual Status setup() = 0; - virtual std::vector<HostAndPort> getListeningPorts() const = 0; - protected: TransportLayer() = default; diff --git a/src/mongo/transport/transport_layer_asio.cpp b/src/mongo/transport/transport_layer_asio.cpp index 4da118247d7..b1dd15f57d7 100644 --- a/src/mongo/transport/transport_layer_asio.cpp +++ b/src/mongo/transport/transport_layer_asio.cpp @@ -281,19 +281,6 @@ void TransportLayerASIO::shutdown() { } } -std::vector<HostAndPort> TransportLayerASIO::getListeningPorts() const { - std::vector<HostAndPort> r; - stdx::lock_guard<stdx::mutex> lk(_mutex); - if (!_running.load()) { - return r; - } - for (auto& acceptor : _acceptors) { - HostAndPort hp = endpointToHostAndPort(acceptor.local_endpoint()); - r.push_back(std::move(hp)); - } - return r; -} - const std::shared_ptr<asio::io_context>& TransportLayerASIO::getIOContext() { return _workerIOContext; } diff --git a/src/mongo/transport/transport_layer_asio.h b/src/mongo/transport/transport_layer_asio.h index bb5433b878f..11cc43e489f 100644 --- a/src/mongo/transport/transport_layer_asio.h +++ b/src/mongo/transport/transport_layer_asio.h @@ -110,8 +110,6 @@ public: void shutdown() final; - std::vector<HostAndPort> getListeningPorts() const final; - const std::shared_ptr<asio::io_context>& getIOContext(); private: @@ -126,7 +124,7 @@ private: void _acceptConnection(GenericAcceptor& acceptor); - mutable stdx::mutex _mutex; + stdx::mutex _mutex; // There are two IO contexts that are used by TransportLayerASIO. The _workerIOContext // contains all the accepted sockets and all normal networking activity. The diff --git a/src/mongo/transport/transport_layer_legacy.cpp b/src/mongo/transport/transport_layer_legacy.cpp index 45ed7ab1fe1..0deea151158 100644 --- a/src/mongo/transport/transport_layer_legacy.cpp +++ b/src/mongo/transport/transport_layer_legacy.cpp @@ -212,14 +212,6 @@ void TransportLayerLegacy::shutdown() { } } -std::vector<HostAndPort> TransportLayerLegacy::getListeningPorts() const { - std::vector<HostAndPort> r; - for (const SockAddr& addr : _listener->getListenerAddrs()) { - r.push_back(HostAndPort(addr)); - } - return r; -} - void TransportLayerLegacy::_destroy(LegacySession& session) { if (!session.conn()->closed) { _closeConnection(session.conn()); diff --git a/src/mongo/transport/transport_layer_legacy.h b/src/mongo/transport/transport_layer_legacy.h index 24a2b7b7dce..47a97b6050d 100644 --- a/src/mongo/transport/transport_layer_legacy.h +++ b/src/mongo/transport/transport_layer_legacy.h @@ -87,8 +87,6 @@ public: void shutdown() override; - std::vector<HostAndPort> getListeningPorts() const final; - private: class LegacySession; using LegacySessionHandle = std::shared_ptr<LegacySession>; diff --git a/src/mongo/transport/transport_layer_manager.cpp b/src/mongo/transport/transport_layer_manager.cpp index 42d35d9c3d7..82e23e1a049 100644 --- a/src/mongo/transport/transport_layer_manager.cpp +++ b/src/mongo/transport/transport_layer_manager.cpp @@ -102,15 +102,6 @@ void TransportLayerManager::shutdown() { _foreach([](TransportLayer* tl) { tl->shutdown(); }); } -std::vector<HostAndPort> TransportLayerManager::getListeningPorts() const { - std::vector<HostAndPort> r; - _foreach([&r](TransportLayer* tl) { - auto hp = tl->getListeningPorts(); - r.insert(r.end(), hp.begin(), hp.end()); - }); - return r; -} - // TODO Same comment as start() Status TransportLayerManager::setup() { for (auto&& tl : _tls) { diff --git a/src/mongo/transport/transport_layer_manager.h b/src/mongo/transport/transport_layer_manager.h index 0d8d71f220f..8349fc56f32 100644 --- a/src/mongo/transport/transport_layer_manager.h +++ b/src/mongo/transport/transport_layer_manager.h @@ -75,8 +75,6 @@ public: void shutdown() override; Status setup() override; - std::vector<HostAndPort> getListeningPorts() const override; - // TODO This method is not called anymore, but may be useful to add new TransportLayers // to the manager after it's been created. Status addAndStartTransportLayer(std::unique_ptr<TransportLayer> tl); diff --git a/src/mongo/transport/transport_layer_mock.h b/src/mongo/transport/transport_layer_mock.h index c4d938a71e4..fd8670818ad 100644 --- a/src/mongo/transport/transport_layer_mock.h +++ b/src/mongo/transport/transport_layer_mock.h @@ -71,8 +71,6 @@ public: void shutdown() override; bool inShutdown() const; - std::vector<HostAndPort> getListeningPorts() const override { return {}; } - private: struct Connection { bool ended; diff --git a/src/mongo/util/net/listen.cpp b/src/mongo/util/net/listen.cpp index 2e5cc394f65..c53e5a2a9b9 100644 --- a/src/mongo/util/net/listen.cpp +++ b/src/mongo/util/net/listen.cpp @@ -168,15 +168,16 @@ bool Listener::setupSockets() { checkTicketNumbers(); } - const bool withUnix = -#if defined(_WIN32) - false; +#if !defined(_WIN32) + _mine = ipToAddrs(_ip.c_str(), _port, (!serverGlobalParams.noUnixSocket && useUnixSockets())); #else - !serverGlobalParams.noUnixSocket && useUnixSockets(); + _mine = ipToAddrs(_ip.c_str(), _port, false); #endif + for (std::vector<SockAddr>::const_iterator it = _mine.begin(), end = _mine.end(); it != end; + ++it) { + const SockAddr& me = *it; - for (const SockAddr& me : ipToAddrs(_ip.c_str(), _port, withUnix)) { if (!me.isValid()) { error() << "listen(): socket is invalid."; return _setupSocketsSuccessful; @@ -233,7 +234,7 @@ bool Listener::setupSockets() { } #endif - _socks.push_back(SockRecord{me, sock}); + _socks.push_back(sock); socketGuard.Dismiss(); } @@ -249,16 +250,16 @@ void Listener::initAndListen() { } SOCKET maxfd = 0; // needed for select() - for (const auto& rec : _socks) { - if (::listen(rec.sock, serverGlobalParams.listenBacklog) != 0) { + for (unsigned i = 0; i < _socks.size(); i++) { + if (::listen(_socks[i], serverGlobalParams.listenBacklog) != 0) { error() << "listen(): listen() failed " << errnoWithDescription(); return; } - ListeningSockets::get()->add(rec.sock); + ListeningSockets::get()->add(_socks[i]); - if (rec.sock > maxfd) { - maxfd = rec.sock; + if (_socks[i] > maxfd) { + maxfd = _socks[i]; } } @@ -288,8 +289,8 @@ void Listener::initAndListen() { fd_set fds[1]; FD_ZERO(fds); - for (const auto& rec : _socks) { - FD_SET(rec.sock, fds); + for (vector<SOCKET>::iterator it = _socks.begin(), end = _socks.end(); it != end; ++it) { + FD_SET(*it, fds); } maxSelectTime.tv_sec = 0; @@ -314,11 +315,11 @@ void Listener::initAndListen() { return; } - for (const auto& rec : _socks) { - if (!(FD_ISSET(rec.sock, fds))) + for (vector<SOCKET>::iterator it = _socks.begin(), end = _socks.end(); it != end; ++it) { + if (!(FD_ISSET(*it, fds))) continue; SockAddr from; - int s = accept(rec.sock, from.raw(), &from.addressSize); + int s = accept(*it, from.raw(), &from.addressSize); if (s < 0) { int x = errno; // so no global issues if (x == EBADF) { @@ -428,13 +429,13 @@ void Listener::initAndListen() { return; } - for (const auto& rec : _socks) { - if (::listen(rec.sock, serverGlobalParams.listenBacklog) != 0) { + for (unsigned i = 0; i < _socks.size(); i++) { + if (::listen(_socks[i], serverGlobalParams.listenBacklog) != 0) { error() << "listen(): listen() failed " << errnoWithDescription(); return; } - ListeningSockets::get()->add(rec.sock); + ListeningSockets::get()->add(_socks[i]); } #ifdef MONGO_CONFIG_SSL @@ -453,6 +454,7 @@ void Listener::initAndListen() { std::vector<std::unique_ptr<EventHolder>> eventHolders; std::unique_ptr<WSAEVENT[]> events(new WSAEVENT[_socks.size()]); + // Populate events array with an event for each socket we are watching for (size_t count = 0; count < _socks.size(); ++count) { auto ev = stdx::make_unique<EventHolder>(); @@ -465,7 +467,7 @@ void Listener::initAndListen() { while (!globalInShutdownDeprecated() && !_finished.load()) { // Turn on listening for accept-ready sockets for (size_t count = 0; count < _socks.size(); ++count) { - int status = WSAEventSelect(_socks[count].sock, events[count], FD_ACCEPT | FD_CLOSE); + int status = WSAEventSelect(_socks[count], events[count], FD_ACCEPT | FD_CLOSE); if (status == SOCKET_ERROR) { const int mongo_errno = WSAGetLastError(); @@ -499,10 +501,9 @@ void Listener::initAndListen() { // Determine which socket is ready DWORD eventIndex = result - WSA_WAIT_EVENT_0; - SOCKET eventSock = _socks[eventIndex].sock; WSANETWORKEVENTS networkEvents; // Extract event details, and clear event for next pass - int status = WSAEnumNetworkEvents(eventSock, events[eventIndex], &networkEvents); + int status = WSAEnumNetworkEvents(_socks[eventIndex], events[eventIndex], &networkEvents); if (status == SOCKET_ERROR) { const int mongo_errno = WSAGetLastError(); error() << "Windows WSAEnumNetworkEvents returned " @@ -526,17 +527,17 @@ void Listener::initAndListen() { continue; } - status = WSAEventSelect(eventSock, NULL, 0); + status = WSAEventSelect(_socks[eventIndex], NULL, 0); if (status == SOCKET_ERROR) { const int mongo_errno = WSAGetLastError(); error() << "Windows WSAEventSelect returned " << errnoWithDescription(mongo_errno); continue; } - disableNonblockingMode(eventSock); + disableNonblockingMode(_socks[eventIndex]); SockAddr from; - int s = accept(eventSock, from.raw(), &from.addressSize); + int s = accept(_socks[eventIndex], from.raw(), &from.addressSize); if (s < 0) { int x = errno; // so no global issues if (x == EBADF) { @@ -651,14 +652,6 @@ void Listener::shutdown() { _finished.store(true); } -std::vector<SockAddr> Listener::getListenerAddrs() const { - std::vector<SockAddr> r; - for (const auto& rec : _socks) { - r.push_back(rec.mine); - } - return r; -} - TicketHolder Listener::globalTicketHolder(DEFAULT_MAX_CONN); AtomicInt64 Listener::globalConnectionNumber; diff --git a/src/mongo/util/net/listen.h b/src/mongo/util/net/listen.h index 6cb97a1acb6..eb473bae009 100644 --- a/src/mongo/util/net/listen.h +++ b/src/mongo/util/net/listen.h @@ -66,6 +66,8 @@ public: /* spawn a thread, etc., then return */ virtual void accepted(std::unique_ptr<AbstractMessagingPort> mp) = 0; + const int _port; + /** * Allocate sockets for the listener and set _setupSocketsSuccessful to true * iff the process was successful. @@ -81,23 +83,17 @@ public: void shutdown(); - std::vector<SockAddr> getListenerAddrs() const; - private: - struct SockRecord { - SockAddr mine; - SOCKET sock; - }; - - std::vector<SockRecord> _socks; - const int _port; + std::vector<SockAddr> _mine; + std::vector<SOCKET> _socks; std::string _name; std::string _ip; bool _setupSocketsSuccessful; bool _logConnect; mutable stdx::mutex _readyMutex; // Protects _ready mutable stdx::condition_variable _readyCondition; // Used to wait for changes to _ready - bool _ready; // Ready to accept incoming network requests? + // Boolean that indicates whether this Listener is ready to accept incoming network requests + bool _ready; AtomicBool _finished{false}; ServiceContext* _ctx; |