mirror of https://github.com/OpenTTD/OpenTTD
Codechange: [Network] Use std::string for NetworkAddress' host name
parent
dcef3209a6
commit
6c4a65eeb8
|
@ -23,11 +23,13 @@ static const int DEFAULT_CONNECT_TIMEOUT_SECONDS = 3; ///< Allow connect() three
|
||||||
*/
|
*/
|
||||||
const char *NetworkAddress::GetHostname()
|
const char *NetworkAddress::GetHostname()
|
||||||
{
|
{
|
||||||
if (StrEmpty(this->hostname) && this->address.ss_family != AF_UNSPEC) {
|
if (this->hostname.empty() && this->address.ss_family != AF_UNSPEC) {
|
||||||
assert(this->address_length != 0);
|
assert(this->address_length != 0);
|
||||||
getnameinfo((struct sockaddr *)&this->address, this->address_length, this->hostname, sizeof(this->hostname), nullptr, 0, NI_NUMERICHOST);
|
char buffer[NETWORK_HOSTNAME_LENGTH];
|
||||||
|
getnameinfo((struct sockaddr *)&this->address, this->address_length, buffer, sizeof(buffer), nullptr, 0, NI_NUMERICHOST);
|
||||||
|
this->hostname = buffer;
|
||||||
}
|
}
|
||||||
return this->hostname;
|
return this->hostname.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,32 +236,32 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList *
|
||||||
/* Setting both hostname to nullptr and port to 0 is not allowed.
|
/* Setting both hostname to nullptr and port to 0 is not allowed.
|
||||||
* As port 0 means bind to any port, the other must mean that
|
* As port 0 means bind to any port, the other must mean that
|
||||||
* we want to bind to 'all' IPs. */
|
* we want to bind to 'all' IPs. */
|
||||||
if (StrEmpty(this->hostname) && this->address_length == 0 && this->GetPort() == 0) {
|
if (this->hostname.empty() && this->address_length == 0 && this->GetPort() == 0) {
|
||||||
reset_hostname = true;
|
reset_hostname = true;
|
||||||
int fam = this->address.ss_family;
|
int fam = this->address.ss_family;
|
||||||
if (fam == AF_UNSPEC) fam = family;
|
if (fam == AF_UNSPEC) fam = family;
|
||||||
strecpy(this->hostname, fam == AF_INET ? "0.0.0.0" : "::", lastof(this->hostname));
|
this->hostname = fam == AF_INET ? "0.0.0.0" : "::";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _resolve_timeout_error_message_shown = false;
|
static bool _resolve_timeout_error_message_shown = false;
|
||||||
auto start = std::chrono::steady_clock::now();
|
auto start = std::chrono::steady_clock::now();
|
||||||
int e = getaddrinfo(StrEmpty(this->hostname) ? nullptr : this->hostname, port_name, &hints, &ai);
|
int e = getaddrinfo(this->hostname.empty() ? nullptr : this->hostname.c_str(), port_name, &hints, &ai);
|
||||||
auto end = std::chrono::steady_clock::now();
|
auto end = std::chrono::steady_clock::now();
|
||||||
std::chrono::seconds duration = std::chrono::duration_cast<std::chrono::seconds>(end - start);
|
std::chrono::seconds duration = std::chrono::duration_cast<std::chrono::seconds>(end - start);
|
||||||
if (!_resolve_timeout_error_message_shown && duration >= std::chrono::seconds(5)) {
|
if (!_resolve_timeout_error_message_shown && duration >= std::chrono::seconds(5)) {
|
||||||
DEBUG(net, 0, "getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s took %i seconds",
|
DEBUG(net, 0, "getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s took %i seconds",
|
||||||
this->hostname, port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), (int)duration.count());
|
this->hostname.c_str(), port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), (int)duration.count());
|
||||||
DEBUG(net, 0, " this is likely an issue in the DNS name resolver's configuration causing it to time out");
|
DEBUG(net, 0, " this is likely an issue in the DNS name resolver's configuration causing it to time out");
|
||||||
_resolve_timeout_error_message_shown = true;
|
_resolve_timeout_error_message_shown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (reset_hostname) strecpy(this->hostname, "", lastof(this->hostname));
|
if (reset_hostname) this->hostname.clear();
|
||||||
|
|
||||||
if (e != 0) {
|
if (e != 0) {
|
||||||
if (func != ResolveLoopProc) {
|
if (func != ResolveLoopProc) {
|
||||||
DEBUG(net, 0, "getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s failed: %s",
|
DEBUG(net, 0, "getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s failed: %s",
|
||||||
this->hostname, port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), FS2OTTD(gai_strerror(e)).c_str());
|
this->hostname.c_str(), port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), FS2OTTD(gai_strerror(e)).c_str());
|
||||||
}
|
}
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
@ -442,11 +444,11 @@ void NetworkAddress::Listen(int socktype, SocketList *sockets)
|
||||||
{
|
{
|
||||||
assert(sockets != nullptr);
|
assert(sockets != nullptr);
|
||||||
|
|
||||||
/* Setting both hostname to nullptr and port to 0 is not allowed.
|
/* Setting both hostname to "" and port to 0 is not allowed.
|
||||||
* As port 0 means bind to any port, the other must mean that
|
* As port 0 means bind to any port, the other must mean that
|
||||||
* we want to bind to 'all' IPs. */
|
* we want to bind to 'all' IPs. */
|
||||||
if (this->address_length == 0 && this->address.ss_family == AF_UNSPEC &&
|
if (this->address_length == 0 && this->address.ss_family == AF_UNSPEC &&
|
||||||
StrEmpty(this->hostname) && this->GetPort() == 0) {
|
this->hostname.empty() && this->GetPort() == 0) {
|
||||||
this->Resolve(AF_INET, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc);
|
this->Resolve(AF_INET, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc);
|
||||||
this->Resolve(AF_INET6, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc);
|
this->Resolve(AF_INET6, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,10 +28,10 @@ typedef SmallMap<NetworkAddress, SOCKET> SocketList; ///< Type for a mapping
|
||||||
*/
|
*/
|
||||||
class NetworkAddress {
|
class NetworkAddress {
|
||||||
private:
|
private:
|
||||||
char hostname[NETWORK_HOSTNAME_LENGTH]; ///< The hostname
|
std::string hostname; ///< The hostname
|
||||||
int address_length; ///< The length of the resolved address
|
int address_length; ///< The length of the resolved address
|
||||||
sockaddr_storage address; ///< The resolved address
|
sockaddr_storage address; ///< The resolved address
|
||||||
bool resolved; ///< Whether the address has been (tried to be) resolved
|
bool resolved; ///< Whether the address has been (tried to be) resolved
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to resolve something to a socket.
|
* Helper function to resolve something to a socket.
|
||||||
|
@ -52,7 +52,6 @@ public:
|
||||||
address(address),
|
address(address),
|
||||||
resolved(address_length != 0)
|
resolved(address_length != 0)
|
||||||
{
|
{
|
||||||
*this->hostname = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,7 +63,6 @@ public:
|
||||||
address_length(address_length),
|
address_length(address_length),
|
||||||
resolved(address_length != 0)
|
resolved(address_length != 0)
|
||||||
{
|
{
|
||||||
*this->hostname = '\0';
|
|
||||||
memset(&this->address, 0, sizeof(this->address));
|
memset(&this->address, 0, sizeof(this->address));
|
||||||
memcpy(&this->address, address, address_length);
|
memcpy(&this->address, address, address_length);
|
||||||
}
|
}
|
||||||
|
@ -75,16 +73,15 @@ public:
|
||||||
* @param port the port
|
* @param port the port
|
||||||
* @param family the address family
|
* @param family the address family
|
||||||
*/
|
*/
|
||||||
NetworkAddress(const char *hostname = "", uint16 port = 0, int family = AF_UNSPEC) :
|
NetworkAddress(std::string_view hostname = "", uint16 port = 0, int family = AF_UNSPEC) :
|
||||||
address_length(0),
|
address_length(0),
|
||||||
resolved(false)
|
resolved(false)
|
||||||
{
|
{
|
||||||
/* Also handle IPv6 bracket enclosed hostnames */
|
if (!hostname.empty() && hostname.front() == '[' && hostname.back() == ']') {
|
||||||
if (StrEmpty(hostname)) hostname = "";
|
hostname.remove_prefix(1);
|
||||||
if (*hostname == '[') hostname++;
|
hostname.remove_suffix(1);
|
||||||
strecpy(this->hostname, StrEmpty(hostname) ? "" : hostname, lastof(this->hostname));
|
}
|
||||||
char *tmp = strrchr(this->hostname, ']');
|
this->hostname = hostname;
|
||||||
if (tmp != nullptr) *tmp = '\0';
|
|
||||||
|
|
||||||
memset(&this->address, 0, sizeof(this->address));
|
memset(&this->address, 0, sizeof(this->address));
|
||||||
this->address.ss_family = family;
|
this->address.ss_family = family;
|
||||||
|
|
|
@ -28,11 +28,11 @@ NetworkUDPSocketHandler::NetworkUDPSocketHandler(NetworkAddressList *bind)
|
||||||
this->bind.push_back(addr);
|
this->bind.push_back(addr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* As hostname nullptr and port 0/nullptr don't go well when
|
/* As an empty hostname and port 0 don't go well when
|
||||||
* resolving it we need to add an address for each of
|
* resolving it we need to add an address for each of
|
||||||
* the address families we support. */
|
* the address families we support. */
|
||||||
this->bind.emplace_back(nullptr, 0, AF_INET);
|
this->bind.emplace_back("", 0, AF_INET);
|
||||||
this->bind.emplace_back(nullptr, 0, AF_INET6);
|
this->bind.emplace_back("", 0, AF_INET6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue