From 294d2150d02950b932cddacf3994e9e1a47abccb Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Mon, 24 Jul 2017 22:44:35 -0500 Subject: [PATCH] Change basic connection to DNS SRV lookup for master server failover --- aoapplication.cpp | 18 +++++++++++++++ aoapplication.h | 3 +++ main.cpp | 2 -- networkmanager.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++- networkmanager.h | 13 ++++++++++- 5 files changed, 87 insertions(+), 4 deletions(-) diff --git a/aoapplication.cpp b/aoapplication.cpp index 179732d..8ee33b0 100644 --- a/aoapplication.cpp +++ b/aoapplication.cpp @@ -12,6 +12,7 @@ AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv) { net_manager = new NetworkManager(this); + QObject::connect(net_manager, SIGNAL(ms_connect_finished(bool)), SLOT(ms_connect_finished(bool))); } AOApplication::~AOApplication() @@ -134,3 +135,20 @@ void AOApplication::loading_cancelled() w_lobby->hide_loading_overlay(); } + +void AOApplication::ms_connect_finished(bool connected) +{ + if (connected) + { + AOPacket *f_packet = new AOPacket("ALL#%"); + send_ms_packet(f_packet); + } + else + { + call_error("There was an error connecting to the master server.\n" + "We deploy multiple master servers to mitigate any possible downtime," + "but the client appears to have exhausted all possible methods of finding" + "and connecting to one.\n" + "Please check your Internet connection and firewall, and please try again."); + } +} diff --git a/aoapplication.h b/aoapplication.h index 34f0f3b..28d176d 100644 --- a/aoapplication.h +++ b/aoapplication.h @@ -146,6 +146,9 @@ private: QVector server_list; QVector favorite_list; +private slots: + void ms_connect_finished(bool connected); + public slots: void server_disconnected(); void loading_cancelled(); diff --git a/main.cpp b/main.cpp index 226d86a..dd45acb 100644 --- a/main.cpp +++ b/main.cpp @@ -14,8 +14,6 @@ int main(int argc, char *argv[]) AOApplication main_app(argc, argv); main_app.construct_lobby(); main_app.net_manager->connect_to_master(); - AOPacket *f_packet = new AOPacket("ALL#%"); - main_app.send_ms_packet(f_packet); main_app.w_lobby->show(); return main_app.exec(); diff --git a/networkmanager.cpp b/networkmanager.cpp index 50c8138..4eaecd7 100644 --- a/networkmanager.cpp +++ b/networkmanager.cpp @@ -27,7 +27,7 @@ void NetworkManager::connect_to_master() ms_socket->close(); ms_socket->abort(); - ms_socket->connectToHost(ms_hostname, ms_port); + perform_srv_lookup(); } void NetworkManager::connect_to_server(server_type p_server) @@ -82,6 +82,59 @@ void NetworkManager::handle_ms_packet() } } +void NetworkManager::perform_srv_lookup() +{ + ms_dns = new QDnsLookup(QDnsLookup::SRV, ms_hostname, this); + + connect(ms_dns, SIGNAL(finished()), this, SLOT(on_srv_lookup())); + ms_dns->lookup(); +} + +void NetworkManager::on_srv_lookup() +{ + bool connected = false; + if (ms_dns->error() != QDnsLookup::NoError) + { + qWarning("SRV lookup of the master server DNS failed."); + ms_dns->deleteLater(); + } + else + { + const auto srv_records = ms_dns->serviceRecords(); + + for (const QDnsServiceRecord &record : srv_records) + { + qDebug() << "Connecting to " << record.target(); + ms_socket->connectToHost(record.target(), record.port()); + QTime timer; + timer.start(); + do + { + ao_app->processEvents(); + if (ms_socket->state() == QAbstractSocket::ConnectedState) + { + connected = true; + break; + } + else if (ms_socket->error() != -1) + { + qWarning(QString("Error connecting to master server: %1").arg(ms_socket->errorString()).toStdString().c_str()); + ms_socket->abort(); + ms_socket->close(); + break; + } + } while (timer.elapsed() < timeout_milliseconds); // Very expensive spin-wait loop - it will bring CPU to 100%! + if (connected) break; + else + { + ms_socket->abort(); + ms_socket->close(); + } + } + } + emit ms_connect_finished(connected); +} + void NetworkManager::handle_server_packet() { char buffer[16384] = {0}; diff --git a/networkmanager.h b/networkmanager.h index 9d366a6..4bfebc6 100644 --- a/networkmanager.h +++ b/networkmanager.h @@ -5,6 +5,8 @@ #include "aoapplication.h" #include +#include +#include class NetworkManager : public QObject { @@ -17,9 +19,11 @@ public: AOApplication *ao_app; QTcpSocket *ms_socket; QTcpSocket *server_socket; + QDnsLookup *ms_dns; - QString ms_hostname = "master.aceattorneyonline.com"; + QString ms_hostname = "_aoms._tcp.aceattorneyonline.com"; int ms_port = 27016; + const int timeout_milliseconds = 2000; bool ms_partial_packet = false; QString ms_temp_packet = ""; @@ -36,7 +40,14 @@ public slots: void ship_ms_packet(QString p_packet); void ship_server_packet(QString p_packet); +signals: + void ms_connect_finished(bool success); + +private: + void perform_srv_lookup(); + private slots: + void on_srv_lookup(); void handle_ms_packet(); void handle_server_packet(); };