Add prefer_ipv6 parameter tp GetHostByNameActor.
GitOrigin-RevId: 727fc30d94657399f1e49efc208b6951a7677d2f
This commit is contained in:
parent
9e6ddb14a7
commit
9b0a138dd1
@ -455,7 +455,8 @@ void ConnectionCreator::ping_proxy(int32 proxy_id, Promise<double> promise) {
|
||||
return promise.set_error(Status::Error(400, "Unknown proxy identifier"));
|
||||
}
|
||||
const Proxy &proxy = it->second;
|
||||
send_closure(get_host_by_name_actor_, &GetHostByNameActor::run, proxy.server().str(), proxy.port(),
|
||||
bool prefer_ipv6 = G()->shared_config().get_option_boolean("prefer_ipv6");
|
||||
send_closure(get_host_by_name_actor_, &GetHostByNameActor::run, proxy.server().str(), proxy.port(), prefer_ipv6,
|
||||
PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise),
|
||||
proxy_id](Result<IPAddress> result) mutable {
|
||||
if (result.is_error()) {
|
||||
@ -1230,8 +1231,9 @@ void ConnectionCreator::loop() {
|
||||
if (resolve_proxy_query_token_ == 0) {
|
||||
resolve_proxy_query_token_ = next_token();
|
||||
const Proxy &proxy = proxies_[active_proxy_id_];
|
||||
bool prefer_ipv6 = G()->shared_config().get_option_boolean("prefer_ipv6");
|
||||
send_closure(
|
||||
get_host_by_name_actor_, &GetHostByNameActor::run, proxy.server().str(), proxy.port(),
|
||||
get_host_by_name_actor_, &GetHostByNameActor::run, proxy.server().str(), proxy.port(), prefer_ipv6,
|
||||
PromiseCreator::lambda([actor_id = create_reference(resolve_proxy_query_token_)](Result<IPAddress> result) {
|
||||
send_closure(std::move(actor_id), &ConnectionCreator::on_proxy_resolved, std::move(result), false);
|
||||
}));
|
||||
|
@ -15,13 +15,13 @@ GetHostByNameActor::GetHostByNameActor(int32 ok_timeout, int32 error_timeout)
|
||||
: ok_timeout_(ok_timeout), error_timeout_(error_timeout) {
|
||||
}
|
||||
|
||||
void GetHostByNameActor::run(std::string host, int port, td::Promise<td::IPAddress> promise) {
|
||||
auto r_ip = load_ip(std::move(host), port);
|
||||
void GetHostByNameActor::run(std::string host, int port, bool prefer_ipv6, td::Promise<td::IPAddress> promise) {
|
||||
auto r_ip = load_ip(std::move(host), port, prefer_ipv6);
|
||||
promise.set_result(std::move(r_ip));
|
||||
}
|
||||
|
||||
Result<td::IPAddress> GetHostByNameActor::load_ip(string host, int port) {
|
||||
auto &value = cache_.emplace(host, Value{{}, 0}).first->second;
|
||||
Result<td::IPAddress> GetHostByNameActor::load_ip(string host, int port, bool prefer_ipv6) {
|
||||
auto &value = cache_[prefer_ipv6].emplace(host, Value{{}, 0}).first->second;
|
||||
auto begin_time = td::Time::now();
|
||||
if (value.expire_at > begin_time) {
|
||||
auto ip = value.ip.clone();
|
||||
@ -33,7 +33,7 @@ Result<td::IPAddress> GetHostByNameActor::load_ip(string host, int port) {
|
||||
}
|
||||
|
||||
td::IPAddress ip;
|
||||
auto status = ip.init_host_port(host, port);
|
||||
auto status = ip.init_host_port(host, port, prefer_ipv6);
|
||||
auto end_time = td::Time::now();
|
||||
LOG(WARNING) << "Init host = " << host << ", port = " << port << " in " << end_time - begin_time << " seconds to "
|
||||
<< ip;
|
||||
|
@ -17,7 +17,7 @@ namespace td {
|
||||
class GetHostByNameActor final : public td::Actor {
|
||||
public:
|
||||
explicit GetHostByNameActor(int32 ok_timeout = CACHE_TIME, int32 error_timeout = ERROR_CACHE_TIME);
|
||||
void run(std::string host, int port, td::Promise<td::IPAddress> promise);
|
||||
void run(std::string host, int port, bool prefer_ipv6, td::Promise<td::IPAddress> promise);
|
||||
|
||||
private:
|
||||
struct Value {
|
||||
@ -27,12 +27,13 @@ class GetHostByNameActor final : public td::Actor {
|
||||
Value(Result<td::IPAddress> ip, double expire_at) : ip(std::move(ip)), expire_at(expire_at) {
|
||||
}
|
||||
};
|
||||
std::unordered_map<string, Value> cache_;
|
||||
std::unordered_map<string, Value> cache_[2];
|
||||
static constexpr int32 CACHE_TIME = 60 * 29; // 29 minutes
|
||||
static constexpr int32 ERROR_CACHE_TIME = 60 * 5; // 5 minutes
|
||||
|
||||
int32 ok_timeout_;
|
||||
int32 error_timeout_;
|
||||
Result<td::IPAddress> load_ip(string host, int port) TD_WARN_UNUSED_RESULT;
|
||||
|
||||
Result<td::IPAddress> load_ip(string host, int port, bool prefer_ipv6) TD_WARN_UNUSED_RESULT;
|
||||
};
|
||||
} // namespace td
|
||||
|
@ -289,12 +289,12 @@ Status IPAddress::init_ipv4_port(CSlice ipv4, int port) {
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status IPAddress::init_host_port(CSlice host, int port) {
|
||||
Status IPAddress::init_host_port(CSlice host, int port, bool prefer_ipv6) {
|
||||
auto str_port = to_string(port);
|
||||
return init_host_port(host, str_port);
|
||||
return init_host_port(host, str_port, prefer_ipv6);
|
||||
}
|
||||
|
||||
Status IPAddress::init_host_port(CSlice host, CSlice port) {
|
||||
Status IPAddress::init_host_port(CSlice host, CSlice port, bool prefer_ipv6) {
|
||||
if (host.empty()) {
|
||||
return Status::Error("Host is empty");
|
||||
}
|
||||
@ -327,14 +327,19 @@ Status IPAddress::init_host_port(CSlice host, CSlice port) {
|
||||
|
||||
addrinfo *best_info = nullptr;
|
||||
for (auto *ptr = info; ptr != nullptr; ptr = ptr->ai_next) {
|
||||
if (ptr->ai_family == AF_INET) {
|
||||
// just use first IPv4 address
|
||||
if (ptr->ai_family == AF_INET && (!prefer_ipv6 || best_info == nullptr)) {
|
||||
// just use first IPv4 address if there is no IPv6 and it isn't preferred
|
||||
best_info = ptr;
|
||||
break;
|
||||
if (!prefer_ipv6) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ptr->ai_family == AF_INET6 && best_info == nullptr) {
|
||||
// or first IPv6 address if there is no IPv4
|
||||
if (ptr->ai_family == AF_INET6 && (prefer_ipv6 || best_info == nullptr)) {
|
||||
// or first IPv6 address if there is no IPv4 and it isn't preferred
|
||||
best_info = ptr;
|
||||
if (prefer_ipv6) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (best_info == nullptr) {
|
||||
|
@ -46,8 +46,8 @@ class IPAddress {
|
||||
Status init_ipv6_port(CSlice ipv6, int port) TD_WARN_UNUSED_RESULT;
|
||||
Status init_ipv6_as_ipv4_port(CSlice ipv4, int port) TD_WARN_UNUSED_RESULT;
|
||||
Status init_ipv4_port(CSlice ipv4, int port) TD_WARN_UNUSED_RESULT;
|
||||
Status init_host_port(CSlice host, int port) TD_WARN_UNUSED_RESULT;
|
||||
Status init_host_port(CSlice host, CSlice port) TD_WARN_UNUSED_RESULT;
|
||||
Status init_host_port(CSlice host, int port, bool prefer_ipv6 = false) TD_WARN_UNUSED_RESULT;
|
||||
Status init_host_port(CSlice host, CSlice port, bool prefer_ipv6 = false) TD_WARN_UNUSED_RESULT;
|
||||
Status init_host_port(CSlice host_port) TD_WARN_UNUSED_RESULT;
|
||||
Status init_socket_address(const SocketFd &socket_fd) TD_WARN_UNUSED_RESULT;
|
||||
Status init_peer_address(const SocketFd &socket_fd) TD_WARN_UNUSED_RESULT;
|
||||
|
Reference in New Issue
Block a user