summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBilly Donahue <billy.donahue@mongodb.com>2017-11-15 14:10:29 -0500
committerBilly Donahue <billy.donahue@mongodb.com>2017-11-15 14:10:29 -0500
commitc748c45d62048c93f9fb4764662b5e2d22d241ad (patch)
tree25415f406847a9106b63125dceb01d5768b6e8c7
parenta784a196d212faded16bd8d11fa1f9368d4e60b0 (diff)
downloadmongo-c748c45d62048c93f9fb4764662b5e2d22d241ad.tar.gz
Revert "SERVER-31808 Query vector<SockAddr> from TransportLayer"
This reverts commit d641ef7968a26a3b84de584faff7437caef748b9.
-rw-r--r--jstests/replsets/localhost3.js11
-rw-r--r--src/mongo/db/repl/repl_set_commands.cpp60
-rw-r--r--src/mongo/shell/servers.js2
-rw-r--r--src/mongo/transport/service_entry_point_test_suite.h4
-rw-r--r--src/mongo/transport/transport_layer.h2
-rw-r--r--src/mongo/transport/transport_layer_asio.cpp13
-rw-r--r--src/mongo/transport/transport_layer_asio.h4
-rw-r--r--src/mongo/transport/transport_layer_legacy.cpp8
-rw-r--r--src/mongo/transport/transport_layer_legacy.h2
-rw-r--r--src/mongo/transport/transport_layer_manager.cpp9
-rw-r--r--src/mongo/transport/transport_layer_manager.h2
-rw-r--r--src/mongo/transport/transport_layer_mock.h2
-rw-r--r--src/mongo/util/net/listen.cpp59
-rw-r--r--src/mongo/util/net/listen.h16
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;