File: NetworkServerLookup.cpp

package info (click to toggle)
jtdx 2.2.159%2Bimproved-3
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 75,336 kB
  • sloc: cpp: 38,503; f90: 31,141; python: 27,061; ansic: 11,772; sh: 409; fortran: 353; makefile: 232
file content (85 lines) | stat: -rw-r--r-- 2,579 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#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);
}