summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonathan Reams <jbreams@mongodb.com>2017-06-20 11:03:42 -0400
committerJonathan Reams <jbreams@mongodb.com>2017-06-27 11:01:03 -0400
commit17d4ddebffb53b85656fa6d370af137691cc1458 (patch)
tree70969d218697dbd4bdd25209f91818e755f53fe4 /src
parent8fe4426fa36587ca40a0b6c8f1c84fd9aa61e5cf (diff)
downloadmongo-17d4ddebffb53b85656fa6d370af137691cc1458.tar.gz
SERVER-29165 Don't create RestrictionEnvironment in TransportLayer
Diffstat (limited to 'src')
-rw-r--r--src/mongo/client/dbclient.cpp4
-rw-r--r--src/mongo/client/dbclient_rs_test.cpp2
-rw-r--r--src/mongo/db/auth/address_restriction.cpp2
-rw-r--r--src/mongo/db/auth/address_restriction_test.cpp2
-rw-r--r--src/mongo/db/auth/authz_session_external_state.cpp2
-rw-r--r--src/mongo/db/auth/restriction.cpp2
-rw-r--r--src/mongo/db/auth/restriction_environment.cpp2
-rw-r--r--src/mongo/db/cursor_manager.cpp2
-rw-r--r--src/mongo/dbtests/mock/mock_conn_registry.cpp2
-rw-r--r--src/mongo/dbtests/mock/mock_dbclient_connection.cpp2
-rw-r--r--src/mongo/dbtests/mock/mock_dbclient_cursor.cpp2
-rw-r--r--src/mongo/dbtests/mock/mock_replica_set.cpp2
-rw-r--r--src/mongo/executor/network_interface_factory.cpp2
-rw-r--r--src/mongo/s/client/shard_connection_test.cpp2
-rw-r--r--src/mongo/s/mongos_options_init.cpp2
-rw-r--r--src/mongo/transport/SConscript1
-rw-r--r--src/mongo/transport/asio_utils.h2
-rw-r--r--src/mongo/transport/service_entry_point_impl.cpp10
-rw-r--r--src/mongo/transport/transport_layer_asio.cpp4
-rw-r--r--src/mongo/transport/transport_layer_legacy.cpp10
-rw-r--r--src/mongo/transport/transport_layer_legacy_test.cpp2
-rw-r--r--src/mongo/util/net/SConscript2
-rw-r--r--src/mongo/util/net/asio_message_port.cpp6
-rw-r--r--src/mongo/util/net/hostandport.cpp4
-rw-r--r--src/mongo/util/net/hostandport.h20
-rw-r--r--src/mongo/util/net/listen.cpp10
-rw-r--r--src/mongo/util/net/sock.cpp11
-rw-r--r--src/mongo/util/net/sock.h5
-rw-r--r--src/mongo/util/net/sockaddr.cpp35
-rw-r--r--src/mongo/util/net/sockaddr.h13
30 files changed, 115 insertions, 52 deletions
diff --git a/src/mongo/client/dbclient.cpp b/src/mongo/client/dbclient.cpp
index 4732658795c..efeab45e926 100644
--- a/src/mongo/client/dbclient.cpp
+++ b/src/mongo/client/dbclient.cpp
@@ -845,7 +845,9 @@ Status DBClientConnection::connectSocketOnly(const HostAndPort& serverAddress) {
_failed = true;
// We need to construct a SockAddr so we can resolve the address.
- SockAddr osAddr{serverAddress.host().c_str(), serverAddress.port()};
+ SockAddr osAddr{serverAddress.host().c_str(),
+ serverAddress.port(),
+ static_cast<sa_family_t>(IPv6Enabled() ? AF_UNSPEC : AF_INET)};
if (!osAddr.isValid()) {
return Status(ErrorCodes::InvalidOptions,
diff --git a/src/mongo/client/dbclient_rs_test.cpp b/src/mongo/client/dbclient_rs_test.cpp
index 15bc9f24a58..b90b4fe75ee 100644
--- a/src/mongo/client/dbclient_rs_test.cpp
+++ b/src/mongo/client/dbclient_rs_test.cpp
@@ -31,6 +31,8 @@
* the DBClientReplicaSet talks to, so the tests only covers the client side logic.
*/
+#include "mongo/platform/basic.h"
+
#include <map>
#include <memory>
#include <string>
diff --git a/src/mongo/db/auth/address_restriction.cpp b/src/mongo/db/auth/address_restriction.cpp
index fb7d626c659..e876d34b127 100644
--- a/src/mongo/db/auth/address_restriction.cpp
+++ b/src/mongo/db/auth/address_restriction.cpp
@@ -26,6 +26,8 @@
* it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/db/auth/address_restriction.h"
namespace mongo {
diff --git a/src/mongo/db/auth/address_restriction_test.cpp b/src/mongo/db/auth/address_restriction_test.cpp
index 19a6c3c780d..865f66f1eb4 100644
--- a/src/mongo/db/auth/address_restriction_test.cpp
+++ b/src/mongo/db/auth/address_restriction_test.cpp
@@ -162,7 +162,7 @@ TEST(AddressRestrictionTest, contains) {
};
for (const auto& p : contains) {
const SockAddr dummy;
- const SockAddr addr(p.address, 1024);
+ const SockAddr addr(p.address, 1024, AF_UNSPEC);
const RestrictionEnvironment rec(addr, dummy);
const RestrictionEnvironment res(dummy, addr);
diff --git a/src/mongo/db/auth/authz_session_external_state.cpp b/src/mongo/db/auth/authz_session_external_state.cpp
index c0dceb9617b..edc3a589d88 100644
--- a/src/mongo/db/auth/authz_session_external_state.cpp
+++ b/src/mongo/db/auth/authz_session_external_state.cpp
@@ -26,6 +26,8 @@
* it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/db/auth/authz_session_external_state.h"
#include "mongo/base/status.h"
diff --git a/src/mongo/db/auth/restriction.cpp b/src/mongo/db/auth/restriction.cpp
index a158f58ede5..a7d55b8ed9e 100644
--- a/src/mongo/db/auth/restriction.cpp
+++ b/src/mongo/db/auth/restriction.cpp
@@ -26,6 +26,8 @@
* it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/db/auth/restriction.h"
namespace mongo {
diff --git a/src/mongo/db/auth/restriction_environment.cpp b/src/mongo/db/auth/restriction_environment.cpp
index 9c07f61db0c..20ddc8f821c 100644
--- a/src/mongo/db/auth/restriction_environment.cpp
+++ b/src/mongo/db/auth/restriction_environment.cpp
@@ -26,6 +26,8 @@
* it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/db/auth/restriction_environment.h"
#include "mongo/transport/session.h"
diff --git a/src/mongo/db/cursor_manager.cpp b/src/mongo/db/cursor_manager.cpp
index a2e9687f5b1..de1b1f0d56e 100644
--- a/src/mongo/db/cursor_manager.cpp
+++ b/src/mongo/db/cursor_manager.cpp
@@ -26,6 +26,8 @@
* it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/db/cursor_manager.h"
#include "mongo/base/data_cursor.h"
diff --git a/src/mongo/dbtests/mock/mock_conn_registry.cpp b/src/mongo/dbtests/mock/mock_conn_registry.cpp
index 61388e337f7..29fd5e0be9b 100644
--- a/src/mongo/dbtests/mock/mock_conn_registry.cpp
+++ b/src/mongo/dbtests/mock/mock_conn_registry.cpp
@@ -26,6 +26,8 @@
* then also delete it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/dbtests/mock/mock_conn_registry.h"
#include "mongo/base/init.h"
diff --git a/src/mongo/dbtests/mock/mock_dbclient_connection.cpp b/src/mongo/dbtests/mock/mock_dbclient_connection.cpp
index 9e7f4467964..b69409b017a 100644
--- a/src/mongo/dbtests/mock/mock_dbclient_connection.cpp
+++ b/src/mongo/dbtests/mock/mock_dbclient_connection.cpp
@@ -25,6 +25,8 @@
* then also delete it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/dbtests/mock/mock_dbclient_connection.h"
#include "mongo/dbtests/mock/mock_dbclient_cursor.h"
diff --git a/src/mongo/dbtests/mock/mock_dbclient_cursor.cpp b/src/mongo/dbtests/mock/mock_dbclient_cursor.cpp
index 4105b866b02..0138e13822b 100644
--- a/src/mongo/dbtests/mock/mock_dbclient_cursor.cpp
+++ b/src/mongo/dbtests/mock/mock_dbclient_cursor.cpp
@@ -27,6 +27,8 @@
* then also delete it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/dbtests/mock/mock_dbclient_cursor.h"
namespace mongo {
diff --git a/src/mongo/dbtests/mock/mock_replica_set.cpp b/src/mongo/dbtests/mock/mock_replica_set.cpp
index 77035a0f8f0..c2c098b4211 100644
--- a/src/mongo/dbtests/mock/mock_replica_set.cpp
+++ b/src/mongo/dbtests/mock/mock_replica_set.cpp
@@ -25,6 +25,8 @@
* then also delete it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/dbtests/mock/mock_replica_set.h"
#include "mongo/db/repl/member_state.h"
diff --git a/src/mongo/executor/network_interface_factory.cpp b/src/mongo/executor/network_interface_factory.cpp
index 2dc7d3f5845..48b4e7a6546 100644
--- a/src/mongo/executor/network_interface_factory.cpp
+++ b/src/mongo/executor/network_interface_factory.cpp
@@ -26,6 +26,8 @@
* it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/executor/network_interface_factory.h"
#include "mongo/base/init.h"
diff --git a/src/mongo/s/client/shard_connection_test.cpp b/src/mongo/s/client/shard_connection_test.cpp
index 1074148f90e..b2fb37be9c4 100644
--- a/src/mongo/s/client/shard_connection_test.cpp
+++ b/src/mongo/s/client/shard_connection_test.cpp
@@ -25,6 +25,8 @@
* then also delete it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include <cstdint>
#include <vector>
diff --git a/src/mongo/s/mongos_options_init.cpp b/src/mongo/s/mongos_options_init.cpp
index 678785e4f88..681e7469679 100644
--- a/src/mongo/s/mongos_options_init.cpp
+++ b/src/mongo/s/mongos_options_init.cpp
@@ -26,6 +26,8 @@
* then also delete it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/s/mongos_options.h"
#include <iostream>
diff --git a/src/mongo/transport/SConscript b/src/mongo/transport/SConscript
index c8b8af833d8..8da74dcae3b 100644
--- a/src/mongo/transport/SConscript
+++ b/src/mongo/transport/SConscript
@@ -85,6 +85,7 @@ env.Library(
'service_state_machine.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/db/auth/authentication_restriction',
"$BUILD_DIR/mongo/db/service_context",
'$BUILD_DIR/mongo/db/stats/counters',
"$BUILD_DIR/mongo/util/processinfo",
diff --git a/src/mongo/transport/asio_utils.h b/src/mongo/transport/asio_utils.h
index eb706f8488c..c06375da31f 100644
--- a/src/mongo/transport/asio_utils.h
+++ b/src/mongo/transport/asio_utils.h
@@ -46,7 +46,7 @@ inline SockAddr endpointToSockAddr(const asio::generic::stream_protocol::endpoin
// Utility function to turn an ASIO endpoint into a mongo HostAndPort
inline HostAndPort endpointToHostAndPort(const asio::generic::stream_protocol::endpoint& endPoint) {
- return HostAndPort(endpointToSockAddr(endPoint).toString(true));
+ return HostAndPort(endpointToSockAddr(endPoint));
}
inline Status errorCodeToStatus(const std::error_code& ec) {
diff --git a/src/mongo/transport/service_entry_point_impl.cpp b/src/mongo/transport/service_entry_point_impl.cpp
index c802e0a8471..2e3ea90eb34 100644
--- a/src/mongo/transport/service_entry_point_impl.cpp
+++ b/src/mongo/transport/service_entry_point_impl.cpp
@@ -34,6 +34,7 @@
#include <vector>
+#include "mongo/db/auth/restriction_environment.h"
#include "mongo/transport/service_entry_point_utils.h"
#include "mongo/transport/service_state_machine.h"
#include "mongo/transport/session.h"
@@ -43,8 +44,17 @@
namespace mongo {
void ServiceEntryPointImpl::startSession(transport::SessionHandle session) {
+ // Setup the restriction environment on the Session, if the Session has local/remote Sockaddrs
+ const auto& remoteAddr = session->remote().sockAddr();
+ const auto& localAddr = session->local().sockAddr();
+ invariant(remoteAddr && localAddr);
+ auto restrictionEnvironment =
+ stdx::make_unique<RestrictionEnvironment>(*localAddr, *remoteAddr);
+ RestrictionEnvironment::set(session, std::move(restrictionEnvironment));
+
// Pass ownership of the transport::SessionHandle into our worker thread. When this
// thread exits, the session will end.
+ //
launchServiceWorkerThread([ this, session = std::move(session) ]() mutable {
_nWorkers.addAndFetch(1);
const auto guard = MakeGuard([this] { _nWorkers.subtractAndFetch(1); });
diff --git a/src/mongo/transport/transport_layer_asio.cpp b/src/mongo/transport/transport_layer_asio.cpp
index 5a2ed22c6ef..25a3e9c7832 100644
--- a/src/mongo/transport/transport_layer_asio.cpp
+++ b/src/mongo/transport/transport_layer_asio.cpp
@@ -201,7 +201,9 @@ Status TransportLayerASIO::setup() {
warning() << "Skipping empty bind address";
continue;
}
- SockAddr addr(ip, _listenerOptions.port);
+ SockAddr addr(StringData(ip),
+ _listenerOptions.port,
+ _listenerOptions.enableIPv6 ? AF_UNSPEC : AF_INET);
asio::generic::stream_protocol::endpoint endpoint(addr.raw(), addr.addressSize);
#ifndef _WIN32
diff --git a/src/mongo/transport/transport_layer_legacy.cpp b/src/mongo/transport/transport_layer_legacy.cpp
index 962b39425e4..843d30cc7e2 100644
--- a/src/mongo/transport/transport_layer_legacy.cpp
+++ b/src/mongo/transport/transport_layer_legacy.cpp
@@ -38,7 +38,6 @@
#include "mongo/base/checked_cast.h"
#include "mongo/config.h"
-#include "mongo/db/auth/restriction_environment.h"
#include "mongo/db/service_context.h"
#include "mongo/db/stats/counters.h"
#include "mongo/stdx/functional.h"
@@ -89,8 +88,8 @@ std::shared_ptr<TransportLayerLegacy::LegacySession> TransportLayerLegacy::Legac
TransportLayerLegacy::LegacySession::LegacySession(std::unique_ptr<AbstractMessagingPort> amp,
TransportLayerLegacy* tl)
- : _remote(amp->remote()),
- _local(amp->localAddr().toString(true)),
+ : _remote(amp->remoteAddr()),
+ _local(amp->localAddr()),
_tl(tl),
_tags(kEmptyTagMask),
_connection(stdx::make_unique<Connection>(std::move(amp))) {}
@@ -328,11 +327,8 @@ void TransportLayerLegacy::_handleNewConnection(std::unique_ptr<AbstractMessagin
}
amp->setLogLevel(logger::LogSeverity::Debug(1));
- auto restrictionEnvironment =
- stdx::make_unique<RestrictionEnvironment>(amp->remoteAddr(), amp->localAddr());
- auto session = LegacySession::create(std::move(amp), this);
- RestrictionEnvironment::set(session, std::move(restrictionEnvironment));
+ auto session = LegacySession::create(std::move(amp), this);
stdx::list<std::weak_ptr<LegacySession>> list;
auto it = list.emplace(list.begin(), session);
diff --git a/src/mongo/transport/transport_layer_legacy_test.cpp b/src/mongo/transport/transport_layer_legacy_test.cpp
index f442b231e9a..103ad622d2b 100644
--- a/src/mongo/transport/transport_layer_legacy_test.cpp
+++ b/src/mongo/transport/transport_layer_legacy_test.cpp
@@ -79,7 +79,7 @@ TEST(TransportLayerLegacy, endSessionsDoesntDoubleClose) {
stdx::thread thr{[&] {
Socket s;
- SockAddr sa{"localhost", 27017};
+ SockAddr sa{"localhost", 27017, AF_INET};
s.connect(sa);
stdx::unique_lock<stdx::mutex> lk(mutex);
diff --git a/src/mongo/util/net/SConscript b/src/mongo/util/net/SConscript
index 8d79bbd06d3..792ee8bd9b6 100644
--- a/src/mongo/util/net/SConscript
+++ b/src/mongo/util/net/SConscript
@@ -8,6 +8,7 @@ env.Library(
target='hostandport',
source=[
'hostandport.cpp',
+ 'sockaddr.cpp',
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
@@ -63,7 +64,6 @@ networkEnv.Library(
"message_port_startup_param.cpp",
"op_msg.cpp",
"sock.cpp",
- "sockaddr.cpp",
'socket_exception.cpp',
"socket_poll.cpp",
"ssl_expiration.cpp",
diff --git a/src/mongo/util/net/asio_message_port.cpp b/src/mongo/util/net/asio_message_port.cpp
index 19413c53435..f12be672592 100644
--- a/src/mongo/util/net/asio_message_port.cpp
+++ b/src/mongo/util/net/asio_message_port.cpp
@@ -482,7 +482,7 @@ HostAndPort ASIOMessagingPort::remote() const {
}
SockAddr ASIOMessagingPort::remoteAddr() const {
- return SockAddr(_remote.host(), _remote.port());
+ return SockAddr(_remote.host(), _remote.port(), AF_UNSPEC);
}
SockAddr ASIOMessagingPort::localAddr() const {
@@ -493,14 +493,14 @@ SockAddr ASIOMessagingPort::localAddr() const {
asio::ip::tcp::endpoint tcpEP;
tcpEP.resize(ep.size());
memcpy(tcpEP.data(), ep.data(), ep.size());
- return SockAddr(tcpEP.address().to_string(), tcpEP.port());
+ return SockAddr(tcpEP.address().to_string(), tcpEP.port(), ep.protocol().family());
}
#ifndef _WIN32
case AF_UNIX: {
asio::local::stream_protocol::endpoint localEP;
localEP.resize(ep.size());
memcpy(localEP.data(), ep.data(), ep.size());
- return SockAddr(localEP.path(), 0);
+ return SockAddr(localEP.path(), 0, AF_UNIX);
}
#endif // _WIN32
default: { MONGO_UNREACHABLE; }
diff --git a/src/mongo/util/net/hostandport.cpp b/src/mongo/util/net/hostandport.cpp
index ad94315e2f7..f4904208830 100644
--- a/src/mongo/util/net/hostandport.cpp
+++ b/src/mongo/util/net/hostandport.cpp
@@ -59,6 +59,10 @@ HostAndPort::HostAndPort(StringData text) {
HostAndPort::HostAndPort(const std::string& h, int p) : _host(h), _port(p) {}
+HostAndPort::HostAndPort(SockAddr addr) : _addr(std::move(addr)) {
+ uassertStatusOK(initialize(_addr->toString(true)));
+}
+
bool HostAndPort::operator<(const HostAndPort& r) const {
const int cmp = host().compare(r.host());
if (cmp)
diff --git a/src/mongo/util/net/hostandport.h b/src/mongo/util/net/hostandport.h
index 74f9fa578a1..540f57f3b46 100644
--- a/src/mongo/util/net/hostandport.h
+++ b/src/mongo/util/net/hostandport.h
@@ -30,8 +30,11 @@
#include <iosfwd>
#include <string>
+#include <boost/optional.hpp>
+
#include "mongo/bson/util/builder.h"
#include "mongo/platform/hash_namespace.h"
+#include "mongo/util/net/sockaddr.h"
namespace mongo {
@@ -75,6 +78,14 @@ struct HostAndPort {
HostAndPort(const std::string& h, int p);
/**
+ * Constructs a HostAndPort from a SockAddr
+ *
+ * Used by the TransportLayer to convert raw socket addresses into HostAndPorts to be
+ * accessed via tranport::Session
+ */
+ explicit HostAndPort(SockAddr addr);
+
+ /**
* (Re-)initializes this HostAndPort by parsing "s". Returns
* Status::OK on success. The state of this HostAndPort is unspecified
* after initialize() returns a non-OK status, though it is safe to
@@ -116,6 +127,14 @@ struct HostAndPort {
*/
bool empty() const;
+ /**
+ * Returns the SockAddr representation of this address, if available
+ */
+ const boost::optional<SockAddr>& sockAddr() const& {
+ return _addr;
+ }
+ void sockAddr() && = delete;
+
const std::string& host() const {
return _host;
}
@@ -126,6 +145,7 @@ struct HostAndPort {
}
private:
+ boost::optional<SockAddr> _addr;
std::string _host;
int _port; // -1 indicates unspecified
};
diff --git a/src/mongo/util/net/listen.cpp b/src/mongo/util/net/listen.cpp
index 7be61a420ee..6e446f14ee1 100644
--- a/src/mongo/util/net/listen.cpp
+++ b/src/mongo/util/net/listen.cpp
@@ -96,13 +96,13 @@ using std::vector;
vector<SockAddr> ipToAddrs(const char* ips, int port, bool useUnixSockets) {
vector<SockAddr> out;
if (*ips == '\0') {
- out.push_back(SockAddr("127.0.0.1", port)); // IPv4 localhost
+ out.push_back(SockAddr("127.0.0.1", port, AF_INET)); // IPv4 localhost
if (IPv6Enabled())
- out.push_back(SockAddr("::1", port)); // IPv6 localhost
+ out.push_back(SockAddr("::1", port, AF_INET6)); // IPv6 localhost
#ifndef _WIN32
if (useUnixSockets)
- out.push_back(SockAddr(makeUnixSockPath(port), port)); // Unix socket
+ out.push_back(SockAddr(makeUnixSockPath(port), port, AF_UNIX)); // Unix socket
#endif
return out;
}
@@ -118,13 +118,13 @@ vector<SockAddr> ipToAddrs(const char* ips, int port, bool useUnixSockets) {
ips = "";
}
- SockAddr sa(ip.c_str(), port);
+ SockAddr sa(ip.c_str(), port, IPv6Enabled() ? AF_UNSPEC : AF_INET);
out.push_back(sa);
#ifndef _WIN32
if (sa.isValid() && useUnixSockets &&
(sa.getAddr() == "127.0.0.1" || sa.getAddr() == "0.0.0.0")) // only IPv4
- out.push_back(SockAddr(makeUnixSockPath(port), port));
+ out.push_back(SockAddr(makeUnixSockPath(port), port, AF_INET));
#endif
}
return out;
diff --git a/src/mongo/util/net/sock.cpp b/src/mongo/util/net/sock.cpp
index 1efc692229b..f0fc3cfde79 100644
--- a/src/mongo/util/net/sock.cpp
+++ b/src/mongo/util/net/sock.cpp
@@ -194,15 +194,6 @@ void disableNagle(int sock) {
#endif
-string getAddrInfoStrError(int code) {
-#if !defined(_WIN32)
- return gai_strerror(code);
-#else
- /* gai_strerrorA is not threadsafe on windows. don't use it. */
- return errnoWithDescription(code);
-#endif
-}
-
// --- SockAddr
string makeUnixSockPath(int port) {
@@ -213,7 +204,7 @@ string makeUnixSockPath(int port) {
// If an ip address is passed in, just return that. If a hostname is passed
// in, look up its ip and return that. Returns "" on failure.
string hostbyname(const char* hostname) {
- SockAddr sockAddr(hostname, 0);
+ SockAddr sockAddr(hostname, 0, IPv6Enabled() ? AF_UNSPEC : AF_INET);
if (!sockAddr.isValid() || sockAddr.getAddr() == "0.0.0.0")
return "";
else
diff --git a/src/mongo/util/net/sock.h b/src/mongo/util/net/sock.h
index 0ba5b20b9a3..18fba961c6d 100644
--- a/src/mongo/util/net/sock.h
+++ b/src/mongo/util/net/sock.h
@@ -68,13 +68,8 @@ struct SSLPeerInfo;
extern const int portSendFlags;
extern const int portRecvFlags;
-const int SOCK_FAMILY_UNKNOWN_ERROR = 13078;
-
void disableNagle(int sock);
-// Generate a string representation for getaddrinfo return codes
-std::string getAddrInfoStrError(int code);
-
#if !defined(_WIN32)
inline void closesocket(int s) {
diff --git a/src/mongo/util/net/sockaddr.cpp b/src/mongo/util/net/sockaddr.cpp
index f9111744b7e..167b5664c32 100644
--- a/src/mongo/util/net/sockaddr.cpp
+++ b/src/mongo/util/net/sockaddr.cpp
@@ -47,10 +47,22 @@
#endif
#include "mongo/bson/util/builder.h"
+#include "mongo/util/itoa.h"
#include "mongo/util/log.h"
-#include "mongo/util/net/sock.h"
namespace mongo {
+namespace {
+constexpr int SOCK_FAMILY_UNKNOWN_ERROR = 13078;
+} // namespace
+
+std::string getAddrInfoStrError(int code) {
+#if !defined(_WIN32)
+ return gai_strerror(code);
+#else
+ /* gai_strerrorA is not threadsafe on windows. don't use it. */
+ return errnoWithDescription(code);
+#endif
+}
SockAddr::SockAddr() {
addressSize = sizeof(sa);
@@ -68,21 +80,21 @@ SockAddr::SockAddr(int sourcePort) {
_isValid = true;
}
-SockAddr::SockAddr(const char* _iporhost, int port) : _hostOrIp(_iporhost) {
- std::string target = _iporhost;
+SockAddr::SockAddr(StringData target, int port, sa_family_t familyHint)
+ : _hostOrIp(target.toString()) {
if (target == "localhost") {
target = "127.0.0.1";
}
- if (mongoutils::str::contains(target, '/')) {
+ if (mongoutils::str::contains(_hostOrIp, '/')) {
#ifdef _WIN32
uassert(13080, "no unix socket support on windows", false);
#endif
uassert(13079,
"path to unix socket too long",
- target.size() < sizeof(as<sockaddr_un>().sun_path));
+ _hostOrIp.size() < sizeof(as<sockaddr_un>().sun_path));
as<sockaddr_un>().sun_family = AF_UNIX;
- strcpy(as<sockaddr_un>().sun_path, target.c_str());
+ strcpy(as<sockaddr_un>().sun_path, _hostOrIp.c_str());
addressSize = sizeof(sockaddr_un);
_isValid = true;
return;
@@ -95,11 +107,10 @@ SockAddr::SockAddr(const char* _iporhost, int port) : _hostOrIp(_iporhost) {
// hints.ai_flags = AI_ADDRCONFIG; // This is often recommended but don't do it.
// SERVER-1579
hints.ai_flags |= AI_NUMERICHOST; // first pass tries w/o DNS lookup
- hints.ai_family = (IPv6Enabled() ? AF_UNSPEC : AF_INET);
+ hints.ai_family = familyHint;
- StringBuilder ss;
- ss << port;
- int ret = getaddrinfo(target.c_str(), ss.str().c_str(), &hints, &addrs);
+ ItoA portStr(port);
+ int ret = getaddrinfo(_hostOrIp.c_str(), StringData(portStr).rawData(), &hints, &addrs);
// old C compilers on IPv6-capable hosts return EAI_NODATA error
#ifdef EAI_NODATA
@@ -110,14 +121,14 @@ SockAddr::SockAddr(const char* _iporhost, int port) : _hostOrIp(_iporhost) {
if ((ret == EAI_NONAME || nodata)) {
// iporhost isn't an IP address, allow DNS lookup
hints.ai_flags &= ~AI_NUMERICHOST;
- ret = getaddrinfo(target.c_str(), ss.str().c_str(), &hints, &addrs);
+ ret = getaddrinfo(_hostOrIp.c_str(), StringData(portStr).rawData(), &hints, &addrs);
}
if (ret) {
// we were unsuccessful
if (target != "0.0.0.0") { // don't log if this as it is a
// CRT construction and log() may not work yet.
- log() << "getaddrinfo(\"" << target << "\") failed: " << getAddrInfoStrError(ret);
+ log() << "getaddrinfo(\"" << _hostOrIp << "\") failed: " << getAddrInfoStrError(ret);
_isValid = false;
return;
}
diff --git a/src/mongo/util/net/sockaddr.h b/src/mongo/util/net/sockaddr.h
index 0f32c48846d..1475d98be1c 100644
--- a/src/mongo/util/net/sockaddr.h
+++ b/src/mongo/util/net/sockaddr.h
@@ -43,6 +43,8 @@
#endif // not _WIN32
+#include "mongo/base/string_data.h"
+
namespace mongo {
#if defined(_WIN32)
@@ -58,16 +60,19 @@ struct sockaddr_un {
#endif // _WIN32
+// Generate a string representation for getaddrinfo return codes
+std::string getAddrInfoStrError(int code);
+
/**
* Wrapper around os representation of network address.
*/
struct SockAddr {
SockAddr();
+
explicit SockAddr(int sourcePort); /* listener side */
- SockAddr(
- const char* ip,
- int port); /* EndPoint (remote) side, or if you want to specify which interface locally */
- SockAddr(const std::string& ip, int port) : SockAddr(ip.c_str(), port) {}
+
+ explicit SockAddr(StringData ip, int port, sa_family_t familyHint);
+
explicit SockAddr(struct sockaddr_storage& other, socklen_t size);
template <typename T>