mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-26 22:28:41 -05:00
86 lines
2.4 KiB
C++
86 lines
2.4 KiB
C++
#include "NetworkServerLookup.hpp"
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <QHostInfo>
|
|
#include <QString>
|
|
|
|
std::tuple<QHostAddress, quint16>
|
|
network_server_lookup (QString query
|
|
, quint16 default_service_port
|
|
, QHostAddress default_host_address
|
|
, QAbstractSocket::NetworkLayerProtocol required_protocol)
|
|
{
|
|
query = query.trimmed ();
|
|
|
|
QHostAddress host_address {default_host_address};
|
|
quint16 service_port {default_service_port};
|
|
|
|
QString host_name;
|
|
if (!query.isEmpty ())
|
|
{
|
|
int port_colon_index {-1};
|
|
|
|
if ('[' == query[0])
|
|
{
|
|
// assume IPv6 combined address/port syntax [<address>]:<port>
|
|
auto close_bracket_index = query.lastIndexOf (']');
|
|
host_name = query.mid (1, close_bracket_index - 1);
|
|
port_colon_index = query.indexOf (':', close_bracket_index);
|
|
}
|
|
else
|
|
{
|
|
port_colon_index = query.lastIndexOf (':');
|
|
host_name = query.left (port_colon_index);
|
|
}
|
|
host_name = host_name.trimmed ();
|
|
|
|
if (port_colon_index >= 0)
|
|
{
|
|
bool ok;
|
|
service_port = query.mid (port_colon_index + 1).trimmed ().toUShort (&ok);
|
|
if (!ok)
|
|
{
|
|
throw std::runtime_error {"network server lookup error: invalid port"};
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!host_name.isEmpty ())
|
|
{
|
|
auto host_info = QHostInfo::fromName (host_name);
|
|
if (host_info.addresses ().isEmpty ())
|
|
{
|
|
throw std::runtime_error {"network server lookup error: host name lookup failed"};
|
|
}
|
|
|
|
bool found {false};
|
|
for (int i {0}; i < host_info.addresses ().size () && !found; ++i)
|
|
{
|
|
host_address = host_info.addresses ().at (i);
|
|
switch (required_protocol)
|
|
{
|
|
case QAbstractSocket::IPv4Protocol:
|
|
case QAbstractSocket::IPv6Protocol:
|
|
if (required_protocol != host_address.protocol ())
|
|
{
|
|
break;
|
|
}
|
|
// fall through
|
|
case QAbstractSocket::AnyIPProtocol:
|
|
found = true;
|
|
break;
|
|
|
|
default:
|
|
throw std::runtime_error {"network server lookup error: invalid required protocol"};
|
|
}
|
|
}
|
|
if (!found)
|
|
{
|
|
throw std::runtime_error {"network server lookup error: no suitable host address found"};
|
|
}
|
|
}
|
|
|
|
return std::make_tuple (host_address, service_port);
|
|
}
|