Merge branch 'topics/mpdiscovery-via-dns' into next
This commit is contained in:
commit
b652758330
8 changed files with 459 additions and 33 deletions
|
@ -131,6 +131,7 @@
|
|||
#include <Instrumentation/HUD/HUD.hxx>
|
||||
#include <Cockpit/cockpitDisplayManager.hxx>
|
||||
#include <Network/HTTPClient.hxx>
|
||||
#include <Network/DNSClient.hxx>
|
||||
#include <Network/fgcom.hxx>
|
||||
#include <Network/http/httpd.hxx>
|
||||
#include <Include/version.h>
|
||||
|
@ -735,6 +736,7 @@ void fgCreateSubsystems(bool duringReset) {
|
|||
if (!globals->get_subsystem<FGHTTPClient>()) {
|
||||
globals->add_new_subsystem<FGHTTPClient>();
|
||||
}
|
||||
globals->add_new_subsystem<FGDNSClient>();
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Initialize the flight model subsystem.
|
||||
|
|
|
@ -3,11 +3,13 @@ include(FlightGearComponent)
|
|||
set(SOURCES
|
||||
multiplaymgr.cxx
|
||||
tiny_xdr.cxx
|
||||
MPServerResolver.cxx
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
multiplaymgr.hxx
|
||||
tiny_xdr.hxx
|
||||
MPServerResolver.hxx
|
||||
)
|
||||
|
||||
flightgear_component(MultiPlayer "${SOURCES}" "${HEADERS}")
|
||||
flightgear_component(MultiPlayer "${SOURCES}" "${HEADERS}")
|
||||
|
|
194
src/MultiPlayer/MPServerResolver.cxx
Normal file
194
src/MultiPlayer/MPServerResolver.cxx
Normal file
|
@ -0,0 +1,194 @@
|
|||
|
||||
/*
|
||||
MPServerResolver.cxx - mpserver names lookup via DNS
|
||||
Written and copyright by Torsten Dreyer - November 2016
|
||||
|
||||
This file is part of FlightGear.
|
||||
|
||||
FlightGear is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FlightGear is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FlightGear. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/#include "MPServerResolver.hxx"
|
||||
|
||||
#include <Network/DNSClient.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <3rdparty/cjson/cJSON.h>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
/**
|
||||
* Build a name=value map from base64 encoded JSON string
|
||||
*/
|
||||
class MPServerProperties : public std::map<string, string> {
|
||||
public:
|
||||
MPServerProperties (string b64)
|
||||
{
|
||||
std::vector<unsigned char> b64dec;
|
||||
simgear::strutils::decodeBase64 (b64, b64dec);
|
||||
auto jsonString = string ((char*) b64dec.data (), b64dec.size ());
|
||||
cJSON * json = ::cJSON_Parse (jsonString.c_str ());
|
||||
if (json) {
|
||||
for (int i = 0; i < ::cJSON_GetArraySize (json); i++) {
|
||||
cJSON * cj = ::cJSON_GetArrayItem (json, i);
|
||||
if (cj->string && cj->valuestring)
|
||||
emplace (cj->string, cj->valuestring);
|
||||
}
|
||||
::cJSON_Delete (json);
|
||||
} else {
|
||||
SG_LOG(SG_NETWORK,SG_WARN, "MPServerResolver: Can't parse JSON string '" << jsonString << "'" );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class MPServerResolver::MPServerResolver_priv {
|
||||
public:
|
||||
enum {
|
||||
INIT, LOADING_SRV_RECORDS, LOAD_NEXT_TXT_RECORD, LOADING_TXT_RECORDS, DONE,
|
||||
} _state = INIT;
|
||||
|
||||
FGDNSClient * _dnsClient = globals->get_subsystem<FGDNSClient> ();
|
||||
DNS::Request_ptr _dnsRequest;
|
||||
PropertyList _serverNodes;
|
||||
PropertyList::const_iterator _serverNodes_it;
|
||||
};
|
||||
|
||||
MPServerResolver::~MPServerResolver ()
|
||||
{
|
||||
delete _priv;
|
||||
}
|
||||
|
||||
MPServerResolver::MPServerResolver () :
|
||||
_priv (new MPServerResolver_priv ())
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MPServerResolver::run ()
|
||||
{
|
||||
//SG_LOG(SG_NETWORK, SG_DEBUG, "MPServerResolver::run() with state=" << _priv->_state );
|
||||
switch (_priv->_state) {
|
||||
// First call - fire DNS lookup for SRV records
|
||||
case MPServerResolver_priv::INIT:
|
||||
if (!_priv->_dnsClient) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "MPServerResolver: DNS subsystem not available.");
|
||||
onFailure ();
|
||||
return;
|
||||
}
|
||||
|
||||
_priv->_dnsRequest = new DNS::SRVRequest (_dnsName, _service, _protocol);
|
||||
SG_LOG(SG_NETWORK, SG_INFO, "MPServerResolver: sending DNS request for " << _priv->_dnsRequest->getDn());
|
||||
_priv->_dnsClient->makeRequest (_priv->_dnsRequest);
|
||||
_priv->_state = MPServerResolver_priv::LOADING_SRV_RECORDS;
|
||||
break;
|
||||
|
||||
// Check if response from SRV Query
|
||||
case MPServerResolver_priv::LOADING_SRV_RECORDS:
|
||||
if (_priv->_dnsRequest->isTimeout ()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Timeout waiting for DNS response. Query was: " << _priv->_dnsRequest->getDn());
|
||||
onFailure ();
|
||||
return;
|
||||
}
|
||||
if (_priv->_dnsRequest->isComplete ()) {
|
||||
// Create a child node under _targetNode for each SRV entry of the response
|
||||
SG_LOG(SG_NETWORK, SG_INFO, "MPServerResolver: got DNS response for " << _priv->_dnsRequest->getDn());
|
||||
int idx = 0;
|
||||
for (DNS::SRVRequest::SRV_ptr entry : dynamic_cast<DNS::SRVRequest*> (_priv->_dnsRequest.get ())->entries) {
|
||||
SG_LOG(SG_NETWORK, SG_DEBUG,
|
||||
"MPServerResolver: SRV " << entry->priority << " " << entry->weight << " " << entry->port << " " << entry->target);
|
||||
if( 0 == entry->port ) {
|
||||
SG_LOG(SG_NETWORK, SG_INFO, "MPServerResolver: Skipping offline host " << entry->target );
|
||||
continue;
|
||||
}
|
||||
SGPropertyNode * serverNode = _targetNode->getNode ("server", idx++, true);
|
||||
serverNode->getNode ("hostname", true)->setStringValue (entry->target);
|
||||
serverNode->getNode ("priority", true)->setIntValue (entry->priority);
|
||||
serverNode->getNode ("weight", true)->setIntValue (entry->weight);
|
||||
serverNode->getNode ("port", true)->setIntValue (entry->port);
|
||||
}
|
||||
|
||||
// prepare an iterator over the server-nodes to be used later when loading the TXT records
|
||||
_priv->_serverNodes = _targetNode->getChildren ("server");
|
||||
_priv->_serverNodes_it = _priv->_serverNodes.begin ();
|
||||
if (_priv->_serverNodes_it == _priv->_serverNodes.end ()) {
|
||||
// No SRV records found - flag failure
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "MPServerResolver: no multiplayer servers defined via DNS");
|
||||
onFailure ();
|
||||
return;
|
||||
}
|
||||
_priv->_state = MPServerResolver_priv::LOAD_NEXT_TXT_RECORD;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// get the next TXT record
|
||||
case MPServerResolver_priv::LOAD_NEXT_TXT_RECORD:
|
||||
if (_priv->_serverNodes_it == _priv->_serverNodes.end ()) {
|
||||
// we are done with all servers
|
||||
_priv->_state = MPServerResolver_priv::DONE;
|
||||
break;
|
||||
}
|
||||
|
||||
// send the DNS query for the hostnames TXT record
|
||||
_priv->_dnsRequest = new DNS::TXTRequest ((*_priv->_serverNodes_it)->getStringValue ("hostname"));
|
||||
SG_LOG(SG_NETWORK, SG_INFO, "MPServerResolver: sending DNS request for " << _priv->_dnsRequest->getDn());
|
||||
_priv->_dnsClient->makeRequest (_priv->_dnsRequest);
|
||||
_priv->_state = MPServerResolver_priv::LOADING_TXT_RECORDS;
|
||||
break;
|
||||
|
||||
// check if response for TXT query
|
||||
case MPServerResolver_priv::LOADING_TXT_RECORDS:
|
||||
if (_priv->_dnsRequest->isTimeout ()) {
|
||||
// on timeout, try proceeding with next server
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Timeout waiting for DNS response. Query was: " << _priv->_dnsRequest->getDn());
|
||||
_priv->_state = MPServerResolver_priv::LOAD_NEXT_TXT_RECORD;
|
||||
++_priv->_serverNodes_it;
|
||||
break;
|
||||
}
|
||||
if (_priv->_dnsRequest->isComplete ()) {
|
||||
SG_LOG(SG_NETWORK, SG_INFO, "MPServerResolver: got DNS response for " << _priv->_dnsRequest->getDn());
|
||||
// DNS::TXTRequest automatically extracts name=value entries for us, lets retrieve them
|
||||
auto attributes = dynamic_cast<DNS::TXTRequest*> (_priv->_dnsRequest.get ())->attributes;
|
||||
auto mpserverAttribute = attributes["flightgear-mpserver"];
|
||||
if (!mpserverAttribute.empty ()) {
|
||||
// we are only interested in the 'flightgear-mpserver=something' entry, this is a base64 encoded
|
||||
// JSON string, convert this into a map<string,string>
|
||||
MPServerProperties mpserverProperties (mpserverAttribute);
|
||||
for (auto prop : mpserverProperties) {
|
||||
// and store each as a node under our servers node.
|
||||
SG_LOG(SG_NETWORK, SG_DEBUG, "MPServerResolver: TXT record attribute " << prop.first << "=" << prop.second);
|
||||
// sanitize property name, don't allow dots or forward slash
|
||||
auto propertyName = prop.first;
|
||||
std::replace( propertyName.begin(), propertyName.end(), '.', '_');
|
||||
std::replace( propertyName.begin(), propertyName.end(), '/', '_');
|
||||
(*_priv->_serverNodes_it)->setStringValue (propertyName, prop.second);
|
||||
}
|
||||
} else {
|
||||
SG_LOG(SG_NETWORK, SG_INFO, "MPServerResolver: TXT record attributes empty");
|
||||
}
|
||||
|
||||
// procede with the net node
|
||||
++_priv->_serverNodes_it;
|
||||
_priv->_state = MPServerResolver_priv::LOAD_NEXT_TXT_RECORD;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MPServerResolver_priv::DONE:
|
||||
onSuccess ();
|
||||
return;
|
||||
}
|
||||
|
||||
// Relinguish control, call me back on the next frame
|
||||
globals->get_event_mgr ()->addEvent ("MPServerResolver_update", this, &MPServerResolver::run, .0);
|
||||
}
|
||||
|
83
src/MultiPlayer/MPServerResolver.hxx
Normal file
83
src/MultiPlayer/MPServerResolver.hxx
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
MPServerResolver.hxx - mpserver names lookup via DNS
|
||||
Written and copyright by Torsten Dreyer - November 2016
|
||||
|
||||
This file is part of FlightGear.
|
||||
|
||||
FlightGear is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FlightGear is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FlightGear. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __FG_MPSERVERRESOLVER_HXX
|
||||
#define __FG_MPSERVERRESOLVER_HXX
|
||||
|
||||
#include <string>
|
||||
#include <simgear/props/props.hxx>
|
||||
|
||||
class MPServerResolver {
|
||||
public:
|
||||
MPServerResolver();
|
||||
virtual ~MPServerResolver();
|
||||
void run();
|
||||
|
||||
/**
|
||||
* Set the target property where the server-list gets stored
|
||||
*
|
||||
* \param value the property node to use as a target
|
||||
*/
|
||||
void setTarget( SGPropertyNode_ptr value ) { _targetNode = value; }
|
||||
|
||||
/**
|
||||
* Set the dns domain name to query. This could be either a full qualified name including the
|
||||
* service and the protocol like _fgms._udp.flightgear.org or just the domain name like
|
||||
* flightgear.org. Use setService() and setProtocol() in the latter case.
|
||||
*
|
||||
* \param value the dnsname to use for the query.
|
||||
*/
|
||||
void setDnsName( const std::string & value ) { _dnsName = value; }
|
||||
|
||||
/** Set the service name to use for the query. Don't add the underscore, this gets added
|
||||
* automatically. This builds the fully qualified DNS name to query, together with
|
||||
* setProtocol() and setDnsName().
|
||||
*
|
||||
* \param value the service name to use for the query sans the leading underscore
|
||||
*/
|
||||
void setService( const std::string & value ) { _service = value; }
|
||||
|
||||
/** Set the protocol name to use for the query. Don't add the underscore, this gets added
|
||||
* automatically. This builds the fully qualified DNS name to query, together with
|
||||
* setService() and setDnsName().
|
||||
*
|
||||
* \param value the protocol name to use for the query sans the leading underscore
|
||||
*/
|
||||
void setProtocol( const std::string & value ) { _protocol = value; }
|
||||
|
||||
/** Handler to be called if the resolver process finishes with success. Does nothing by
|
||||
* default and should be overridden be the user.
|
||||
*/
|
||||
virtual void onSuccess() {};
|
||||
|
||||
/** Handler to be called if the resolver process terminates with an error. Does nothing by
|
||||
* default and should be overridden be the user.
|
||||
*/
|
||||
virtual void onFailure() {};
|
||||
|
||||
private:
|
||||
class MPServerResolver_priv;
|
||||
std::string _dnsName;
|
||||
std::string _service;
|
||||
std::string _protocol;
|
||||
SGPropertyNode_ptr _targetNode;
|
||||
MPServerResolver_priv * _priv;
|
||||
};
|
||||
|
||||
#endif // __FG_MPSERVERRESOLVER_HXX
|
|
@ -41,14 +41,14 @@
|
|||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/structure/commands.hxx>
|
||||
#include <simgear/structure/event_mgr.hxx>
|
||||
|
||||
#include <AIModel/AIManager.hxx>
|
||||
#include <AIModel/AIMultiplayer.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Network/RemoteXMLRequest.hxx>
|
||||
#include <Network/HTTPClient.hxx>
|
||||
#include "multiplaymgr.hxx"
|
||||
#include "mpmessages.hxx"
|
||||
#include "MPServerResolver.hxx"
|
||||
#include <FDM/flightProperties.hxx>
|
||||
|
||||
using namespace std;
|
||||
|
@ -428,40 +428,60 @@ static bool do_multiplayer_disconnect(const SGPropertyNode * arg) {
|
|||
// none
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
static bool do_multiplayer_refreshserverlist(const SGPropertyNode * arg) {
|
||||
FGMultiplayMgr * self = (FGMultiplayMgr*) globals->get_subsystem("mp");
|
||||
if (!self) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Multiplayer subsystem not available.");
|
||||
return false;
|
||||
}
|
||||
|
||||
FGHTTPClient* http = globals->get_subsystem<FGHTTPClient>();
|
||||
if (!http) {
|
||||
SG_LOG(SG_IO, SG_ALERT,
|
||||
"do_multiplayer.refreshserverlist: HTTP client not running");
|
||||
return false;
|
||||
}
|
||||
static bool
|
||||
do_multiplayer_refreshserverlist (const SGPropertyNode * arg)
|
||||
{
|
||||
using namespace simgear;
|
||||
|
||||
string url(
|
||||
fgGetString("/sim/multiplay/serverlist-url",
|
||||
"http://liveries.flightgear.org/mpstatus/mpservers.xml"));
|
||||
FGMultiplayMgr * self = (FGMultiplayMgr*) globals->get_subsystem ("mp");
|
||||
if (!self) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Multiplayer subsystem not available.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url.empty()) {
|
||||
SG_LOG(SG_IO, SG_ALERT,
|
||||
"do_multiplayer.refreshserverlist: no URL given");
|
||||
return false;
|
||||
}
|
||||
// MPServerResolver implementation to fill the mp server list
|
||||
// deletes itself when done
|
||||
class MyMPServerResolver : public MPServerResolver {
|
||||
public:
|
||||
MyMPServerResolver () :
|
||||
MPServerResolver ()
|
||||
{
|
||||
setTarget (fgGetNode ("/sim/multiplay/server-list", true));
|
||||
setDnsName (fgGetString ("/sim/multiplay/dns/query-dn", "flightgear.org"));
|
||||
setService (fgGetString ("/sim/multiplay/dns/query-srv-service", "fgms"));
|
||||
setProtocol (fgGetString ("/sim/multiplay/dns/query-srv-protocol", "udp"));
|
||||
_completeNode->setBoolValue (false);
|
||||
_failureNode->setBoolValue (false);
|
||||
}
|
||||
|
||||
SGPropertyNode *targetnode = fgGetNode("/sim/multiplay/server-list", true);
|
||||
SGPropertyNode *completeNode = fgGetNode("/sim/multiplay/got-servers", true);
|
||||
SGPropertyNode *failureNode = fgGetNode("/sim/multiplay/get-servers-failure", true);
|
||||
RemoteXMLRequest* req = new RemoteXMLRequest(url, targetnode);
|
||||
req->setCompletionProp(completeNode);
|
||||
req->setFailedProp(failureNode);
|
||||
completeNode->setBoolValue(false);
|
||||
failureNode->setBoolValue(false);
|
||||
http->makeRequest(req);
|
||||
return true;
|
||||
~MyMPServerResolver ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void
|
||||
onSuccess ()
|
||||
{
|
||||
SG_LOG(SG_NETWORK, SG_DEBUG, "MyMPServerResolver: trigger success");
|
||||
_completeNode->setBoolValue (true);
|
||||
delete this;
|
||||
}
|
||||
virtual void
|
||||
onFailure ()
|
||||
{
|
||||
SG_LOG(SG_NETWORK, SG_DEBUG, "MyMPServerResolver: trigger failure");
|
||||
_failureNode->setBoolValue (true);
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
SGPropertyNode *_completeNode = fgGetNode ("/sim/multiplay/got-servers", true);
|
||||
SGPropertyNode *_failureNode = fgGetNode ("/sim/multiplay/get-servers-failure", true);
|
||||
};
|
||||
|
||||
MyMPServerResolver * mpServerResolver = new MyMPServerResolver ();
|
||||
mpServerResolver->run ();
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -11,6 +11,7 @@ set(SOURCES
|
|||
garmin.cxx
|
||||
generic.cxx
|
||||
HTTPClient.cxx
|
||||
DNSClient.cxx
|
||||
igc.cxx
|
||||
joyclient.cxx
|
||||
jsclient.cxx
|
||||
|
@ -39,6 +40,7 @@ set(HEADERS
|
|||
garmin.hxx
|
||||
generic.hxx
|
||||
HTTPClient.hxx
|
||||
DNSClient.hxx
|
||||
igc.hxx
|
||||
joyclient.hxx
|
||||
jsclient.hxx
|
||||
|
|
71
src/Network/DNSClient.cxx
Normal file
71
src/Network/DNSClient.cxx
Normal file
|
@ -0,0 +1,71 @@
|
|||
// HDNSClient.cxx -- Singleton DNS client object
|
||||
//
|
||||
// Written by James Turner, started April 2012.
|
||||
// Based on HTTPClient from James Turner
|
||||
// Copyright (C) 2012 James Turner
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#include "DNSClient.hxx"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Include/version.h>
|
||||
|
||||
#include <simgear/sg_inlines.h>
|
||||
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
FGDNSClient::FGDNSClient() :
|
||||
_inited(false)
|
||||
{
|
||||
}
|
||||
|
||||
FGDNSClient::~FGDNSClient()
|
||||
{
|
||||
}
|
||||
|
||||
void FGDNSClient::init()
|
||||
{
|
||||
if (_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
_dns.reset( new simgear::DNS::Client() );
|
||||
|
||||
_inited = true;
|
||||
}
|
||||
|
||||
void FGDNSClient::postinit()
|
||||
{
|
||||
}
|
||||
|
||||
void FGDNSClient::shutdown()
|
||||
{
|
||||
_dns.reset();
|
||||
_inited = false;
|
||||
}
|
||||
|
||||
void FGDNSClient::update(double)
|
||||
{
|
||||
_dns->update();
|
||||
}
|
||||
|
||||
void FGDNSClient::makeRequest(const simgear::DNS::Request_ptr& req)
|
||||
{
|
||||
_dns->makeRequest(req);
|
||||
}
|
52
src/Network/DNSClient.hxx
Normal file
52
src/Network/DNSClient.hxx
Normal file
|
@ -0,0 +1,52 @@
|
|||
// DNSClient.hxx -- Singleton DNS client object
|
||||
//
|
||||
// Written by Torsten Dreyer, started November 2016.
|
||||
// Based on HTTPClient from James Turner
|
||||
// Copyright (C) 2012 James Turner
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#ifndef FG_DNS_CLIENT_HXX
|
||||
#define FG_DNS_CLIENT_HXX
|
||||
|
||||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/io/DNSClient.hxx>
|
||||
#include <memory>
|
||||
|
||||
class FGDNSClient : public SGSubsystem
|
||||
{
|
||||
public:
|
||||
FGDNSClient();
|
||||
virtual ~FGDNSClient();
|
||||
|
||||
void makeRequest(const simgear::DNS::Request_ptr& req);
|
||||
|
||||
// simgear::HTTP::Client* client() { return _http.get(); }
|
||||
// simgear::HTTP::Client const* client() const { return _http.get(); }
|
||||
|
||||
virtual void init();
|
||||
virtual void postinit();
|
||||
virtual void shutdown();
|
||||
virtual void update(double);
|
||||
|
||||
static const char* subsystemName() { return "dns"; }
|
||||
private:
|
||||
bool _inited;
|
||||
std::unique_ptr<simgear::DNS::Client> _dns;
|
||||
};
|
||||
|
||||
#endif // FG_DNS_CLIENT_HXX
|
||||
|
||||
|
Loading…
Add table
Reference in a new issue