73 switch (_priv->_state) {
76 if (!_priv->_dnsClient) {
77 SG_LOG(SG_NETWORK, SG_WARN,
"MPServerResolver: DNS subsystem not available.");
82 _priv->_dnsRequest =
new DNS::SRVRequest (_dnsName, _service, _protocol);
83 SG_LOG(SG_NETWORK, SG_INFO,
"MPServerResolver: sending DNS request for " << _priv->_dnsRequest->getDn());
84 _priv->_dnsClient->makeRequest (_priv->_dnsRequest);
90 if (_priv->_dnsRequest->isTimeout ()) {
91 SG_LOG(SG_NETWORK, SG_WARN,
"Timeout waiting for DNS response. Query was: " << _priv->_dnsRequest->getDn());
95 if (_priv->_dnsRequest->isComplete ()) {
97 SG_LOG(SG_NETWORK, SG_INFO,
"MPServerResolver: got DNS response for " << _priv->_dnsRequest->getDn());
99 for (DNS::SRVRequest::SRV_ptr entry :
dynamic_cast<DNS::SRVRequest*
> (_priv->_dnsRequest.get ())->entries) {
100 SG_LOG(SG_NETWORK, SG_DEBUG,
101 "MPServerResolver: SRV " << entry->priority <<
" " << entry->weight <<
" " << entry->port <<
" " << entry->target);
102 if( 0 == entry->port ) {
103 SG_LOG(SG_NETWORK, SG_INFO,
"MPServerResolver: Skipping offline host " << entry->target );
106 SGPropertyNode * serverNode = _targetNode->getNode (
"server", idx++,
true);
107 serverNode->getNode (
"hostname",
true)->setStringValue (entry->target);
108 serverNode->getNode (
"priority",
true)->setIntValue (entry->priority);
109 serverNode->getNode (
"weight",
true)->setIntValue (entry->weight);
110 serverNode->getNode (
"port",
true)->setIntValue (entry->port);
114 _priv->_serverNodes = _targetNode->getChildren (
"server");
115 _priv->_serverNodes_it = _priv->_serverNodes.begin ();
116 if (_priv->_serverNodes_it == _priv->_serverNodes.end ()) {
118 SG_LOG(SG_NETWORK, SG_WARN,
"MPServerResolver: no multiplayer servers defined via DNS");
129 if (_priv->_serverNodes_it == _priv->_serverNodes.end ()) {
136 _priv->_dnsRequest =
new DNS::TXTRequest ((*_priv->_serverNodes_it)->getStringValue (
"hostname"));
137 SG_LOG(SG_NETWORK, SG_INFO,
"MPServerResolver: sending DNS request for " << _priv->_dnsRequest->getDn());
138 _priv->_dnsClient->makeRequest (_priv->_dnsRequest);
144 if (_priv->_dnsRequest->isTimeout ()) {
146 SG_LOG(SG_NETWORK, SG_WARN,
"Timeout waiting for DNS response. Query was: " << _priv->_dnsRequest->getDn());
148 ++_priv->_serverNodes_it;
151 if (_priv->_dnsRequest->isComplete ()) {
152 SG_LOG(SG_NETWORK, SG_INFO,
"MPServerResolver: got DNS response for " << _priv->_dnsRequest->getDn());
154 auto attributes =
dynamic_cast<DNS::TXTRequest*
> (_priv->_dnsRequest.get ())->attributes;
155 auto mpserverAttribute = attributes[
"flightgear-mpserver"];
156 if (!mpserverAttribute.empty ()) {
160 for (
auto prop : mpserverProperties) {
162 SG_LOG(SG_NETWORK, SG_DEBUG,
"MPServerResolver: TXT record attribute " << prop.first <<
"=" << prop.second);
164 auto propertyName = prop.first;
165 std::replace( propertyName.begin(), propertyName.end(),
'.',
'_');
166 std::replace( propertyName.begin(), propertyName.end(),
'/',
'_');
167 (*_priv->_serverNodes_it)->setStringValue (propertyName, prop.second);
170 SG_LOG(SG_NETWORK, SG_INFO,
"MPServerResolver: TXT record attributes empty");
174 ++_priv->_serverNodes_it;
181 _priv->_dnsRequest.clear();
187 globals->get_event_mgr ()->addEvent (
"MPServerResolver_update", [
this](){ this->
run(); }, .0);