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