mirror of
https://github.com/apple/foundationdb.git
synced 2025-05-15 02:18:39 +08:00
Add DNS cache.
This commit is contained in:
parent
ff934ca2ad
commit
e548c0d604
@ -131,7 +131,8 @@ UID SimExternalConnection::getDebugID() const {
|
||||
}
|
||||
|
||||
std::vector<NetworkAddress> SimExternalConnection::resolveTCPEndpointBlocking(const std::string& host,
|
||||
const std::string& service) {
|
||||
const std::string& service,
|
||||
DNSCache* dnsCache) {
|
||||
ip::tcp::resolver resolver(ios);
|
||||
try {
|
||||
auto iter = resolver.resolve(host, service);
|
||||
@ -147,20 +148,28 @@ std::vector<NetworkAddress> SimExternalConnection::resolveTCPEndpointBlocking(co
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
if (addrs.empty()) {
|
||||
throw lookup_failed();
|
||||
}
|
||||
dnsCache->add(host, service, addrs);
|
||||
return addrs;
|
||||
} catch (...) {
|
||||
dnsCache->remove(host, service);
|
||||
throw lookup_failed();
|
||||
}
|
||||
}
|
||||
|
||||
ACTOR static Future<std::vector<NetworkAddress>> resolveTCPEndpointImpl(std::string host, std::string service) {
|
||||
ACTOR static Future<std::vector<NetworkAddress>> resolveTCPEndpointImpl(std::string host,
|
||||
std::string service,
|
||||
DNSCache* dnsCache) {
|
||||
wait(delayJittered(0.1));
|
||||
return SimExternalConnection::resolveTCPEndpointBlocking(host, service);
|
||||
return SimExternalConnection::resolveTCPEndpointBlocking(host, service, dnsCache);
|
||||
}
|
||||
|
||||
Future<std::vector<NetworkAddress>> SimExternalConnection::resolveTCPEndpoint(const std::string& host,
|
||||
const std::string& service) {
|
||||
return resolveTCPEndpointImpl(host, service);
|
||||
const std::string& service,
|
||||
DNSCache* dnsCache) {
|
||||
return resolveTCPEndpointImpl(host, service, dnsCache);
|
||||
}
|
||||
|
||||
Future<Reference<IConnection>> SimExternalConnection::connect(NetworkAddress toAddr) {
|
||||
|
@ -48,8 +48,12 @@ public:
|
||||
int write(SendBuffer const* buffer, int limit) override;
|
||||
NetworkAddress getPeerAddress() const override;
|
||||
UID getDebugID() const override;
|
||||
static Future<std::vector<NetworkAddress>> resolveTCPEndpoint(const std::string& host, const std::string& service);
|
||||
static std::vector<NetworkAddress> resolveTCPEndpointBlocking(const std::string& host, const std::string& service);
|
||||
static Future<std::vector<NetworkAddress>> resolveTCPEndpoint(const std::string& host,
|
||||
const std::string& service,
|
||||
DNSCache* dnsCache);
|
||||
static std::vector<NetworkAddress> resolveTCPEndpointBlocking(const std::string& host,
|
||||
const std::string& service,
|
||||
DNSCache* dnsCache);
|
||||
static Future<Reference<IConnection>> connect(NetworkAddress toAddr);
|
||||
};
|
||||
|
||||
|
@ -981,7 +981,20 @@ public:
|
||||
if (mock.present()) {
|
||||
return mock.get();
|
||||
}
|
||||
return SimExternalConnection::resolveTCPEndpoint(host, service);
|
||||
return SimExternalConnection::resolveTCPEndpoint(host, service, &dnsCache);
|
||||
}
|
||||
Future<std::vector<NetworkAddress>> resolveTCPEndpointWithDNSCache(const std::string& host,
|
||||
const std::string& service) override {
|
||||
// If a <hostname, vector<NetworkAddress>> pair was injected to mock DNS, use it.
|
||||
Optional<std::vector<NetworkAddress>> mock = mockDNS.find(host, service);
|
||||
if (mock.present()) {
|
||||
return mock.get();
|
||||
}
|
||||
Optional<std::vector<NetworkAddress>> cache = dnsCache.find(host, service);
|
||||
if (cache.present()) {
|
||||
return cache.get();
|
||||
}
|
||||
return SimExternalConnection::resolveTCPEndpoint(host, service, &dnsCache);
|
||||
}
|
||||
std::vector<NetworkAddress> resolveTCPEndpointBlocking(const std::string& host,
|
||||
const std::string& service) override {
|
||||
@ -990,7 +1003,20 @@ public:
|
||||
if (mock.present()) {
|
||||
return mock.get();
|
||||
}
|
||||
return SimExternalConnection::resolveTCPEndpointBlocking(host, service);
|
||||
return SimExternalConnection::resolveTCPEndpointBlocking(host, service, &dnsCache);
|
||||
}
|
||||
std::vector<NetworkAddress> resolveTCPEndpointBlockingWithDNSCache(const std::string& host,
|
||||
const std::string& service) override {
|
||||
// If a <hostname, vector<NetworkAddress>> pair was injected to mock DNS, use it.
|
||||
Optional<std::vector<NetworkAddress>> mock = mockDNS.find(host, service);
|
||||
if (mock.present()) {
|
||||
return mock.get();
|
||||
}
|
||||
Optional<std::vector<NetworkAddress>> cache = dnsCache.find(host, service);
|
||||
if (cache.present()) {
|
||||
return cache.get();
|
||||
}
|
||||
return SimExternalConnection::resolveTCPEndpointBlocking(host, service, &dnsCache);
|
||||
}
|
||||
ACTOR static Future<Reference<IConnection>> onConnect(Future<Void> ready, Reference<Sim2Conn> conn) {
|
||||
wait(ready);
|
||||
|
@ -166,8 +166,12 @@ public:
|
||||
|
||||
Future<std::vector<NetworkAddress>> resolveTCPEndpoint(const std::string& host,
|
||||
const std::string& service) override;
|
||||
Future<std::vector<NetworkAddress>> resolveTCPEndpointWithDNSCache(const std::string& host,
|
||||
const std::string& service) override;
|
||||
std::vector<NetworkAddress> resolveTCPEndpointBlocking(const std::string& host,
|
||||
const std::string& service) override;
|
||||
std::vector<NetworkAddress> resolveTCPEndpointBlockingWithDNSCache(const std::string& host,
|
||||
const std::string& service) override;
|
||||
Reference<IListener> listen(NetworkAddress localAddr) override;
|
||||
|
||||
// INetwork interface
|
||||
@ -1837,6 +1841,14 @@ Future<Reference<IConnection>> Net2::connectExternal(NetworkAddress toAddr, cons
|
||||
return connect(toAddr, host);
|
||||
}
|
||||
|
||||
Future<Reference<IUDPSocket>> Net2::createUDPSocket(NetworkAddress toAddr) {
|
||||
return UDPSocket::connect(&reactor.ios, toAddr, toAddr.ip.isV6());
|
||||
}
|
||||
|
||||
Future<Reference<IUDPSocket>> Net2::createUDPSocket(bool isV6) {
|
||||
return UDPSocket::connect(&reactor.ios, Optional<NetworkAddress>(), isV6);
|
||||
}
|
||||
|
||||
ACTOR static Future<std::vector<NetworkAddress>> resolveTCPEndpoint_impl(Net2* self,
|
||||
std::string host,
|
||||
std::string service) {
|
||||
@ -1847,6 +1859,7 @@ ACTOR static Future<std::vector<NetworkAddress>> resolveTCPEndpoint_impl(Net2* s
|
||||
tcpResolver.async_resolve(tcp::resolver::query(host, service),
|
||||
[=](const boost::system::error_code& ec, tcp::resolver::iterator iter) {
|
||||
if (ec) {
|
||||
self->dnsCache.remove(host, service);
|
||||
promise.sendError(lookup_failed());
|
||||
return;
|
||||
}
|
||||
@ -1866,6 +1879,7 @@ ACTOR static Future<std::vector<NetworkAddress>> resolveTCPEndpoint_impl(Net2* s
|
||||
}
|
||||
|
||||
if (addrs.empty()) {
|
||||
self->dnsCache.remove(host, service);
|
||||
promise.sendError(lookup_failed());
|
||||
} else {
|
||||
promise.send(addrs);
|
||||
@ -1874,22 +1888,25 @@ ACTOR static Future<std::vector<NetworkAddress>> resolveTCPEndpoint_impl(Net2* s
|
||||
|
||||
wait(ready(result));
|
||||
tcpResolver.cancel();
|
||||
std::vector<NetworkAddress> ret = result.get();
|
||||
self->dnsCache.add(host, service, ret);
|
||||
|
||||
return result.get();
|
||||
}
|
||||
|
||||
Future<Reference<IUDPSocket>> Net2::createUDPSocket(NetworkAddress toAddr) {
|
||||
return UDPSocket::connect(&reactor.ios, toAddr, toAddr.ip.isV6());
|
||||
}
|
||||
|
||||
Future<Reference<IUDPSocket>> Net2::createUDPSocket(bool isV6) {
|
||||
return UDPSocket::connect(&reactor.ios, Optional<NetworkAddress>(), isV6);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Future<std::vector<NetworkAddress>> Net2::resolveTCPEndpoint(const std::string& host, const std::string& service) {
|
||||
return resolveTCPEndpoint_impl(this, host, service);
|
||||
}
|
||||
|
||||
Future<std::vector<NetworkAddress>> Net2::resolveTCPEndpointWithDNSCache(const std::string& host,
|
||||
const std::string& service) {
|
||||
Optional<std::vector<NetworkAddress>> cache = dnsCache.find(host, service);
|
||||
if (cache.present()) {
|
||||
return cache.get();
|
||||
}
|
||||
return resolveTCPEndpoint_impl(this, host, service);
|
||||
}
|
||||
|
||||
std::vector<NetworkAddress> Net2::resolveTCPEndpointBlocking(const std::string& host, const std::string& service) {
|
||||
tcp::resolver tcpResolver(reactor.ios);
|
||||
try {
|
||||
@ -1906,12 +1923,25 @@ std::vector<NetworkAddress> Net2::resolveTCPEndpointBlocking(const std::string&
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
if (addrs.empty()) {
|
||||
throw lookup_failed();
|
||||
}
|
||||
return addrs;
|
||||
} catch (...) {
|
||||
dnsCache.remove(host, service);
|
||||
throw lookup_failed();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<NetworkAddress> Net2::resolveTCPEndpointBlockingWithDNSCache(const std::string& host,
|
||||
const std::string& service) {
|
||||
Optional<std::vector<NetworkAddress>> cache = dnsCache.find(host, service);
|
||||
if (cache.present()) {
|
||||
return cache.get();
|
||||
}
|
||||
return resolveTCPEndpointBlocking(host, service);
|
||||
}
|
||||
|
||||
bool Net2::isAddressOnThisHost(NetworkAddress const& addr) const {
|
||||
auto it = addressOnHostCache.find(addr.ip);
|
||||
if (it != addressOnHostCache.end())
|
||||
|
@ -745,10 +745,17 @@ public:
|
||||
// NetworkAddresses
|
||||
virtual Future<std::vector<NetworkAddress>> resolveTCPEndpoint(const std::string& host,
|
||||
const std::string& service) = 0;
|
||||
// Similar to resolveTCPEndpoint(), except that this one uses DNS cache.
|
||||
virtual Future<std::vector<NetworkAddress>> resolveTCPEndpointWithDNSCache(const std::string& host,
|
||||
const std::string& service) = 0;
|
||||
// Resolve host name and service name. This one should only be used when resolving asynchronously is impossible. For
|
||||
// all other cases, resolveTCPEndpoint() should be preferred.
|
||||
virtual std::vector<NetworkAddress> resolveTCPEndpointBlocking(const std::string& host,
|
||||
const std::string& service) = 0;
|
||||
// Resolve host name and service name with DNS cache. This one should only be used when resolving asynchronously is
|
||||
// impossible. For all other cases, resolveTCPEndpointWithDNSCache() should be preferred.
|
||||
virtual std::vector<NetworkAddress> resolveTCPEndpointBlockingWithDNSCache(const std::string& host,
|
||||
const std::string& service) = 0;
|
||||
|
||||
// Convenience function to resolve host/service and connect to one of its NetworkAddresses randomly
|
||||
// isTLS has to be a parameter here because it is passed to connect() as part of the toAddr object.
|
||||
@ -762,6 +769,11 @@ public:
|
||||
static INetworkConnections* net() {
|
||||
return static_cast<INetworkConnections*>((void*)g_network->global(INetwork::enNetworkConnections));
|
||||
}
|
||||
|
||||
void removeCachedDNS(const std::string& host, const std::string& service) { dnsCache.remove(host, service); }
|
||||
|
||||
DNSCache dnsCache;
|
||||
|
||||
// Returns the interface that should be used to make and accept socket connections
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user