qBittorrent
Net::DNSUpdater Class Reference

#include <dnsupdater.h>

Inheritance diagram for Net::DNSUpdater:
Collaboration diagram for Net::DNSUpdater:

Public Slots

void updateCredentials ()
 

Public Member Functions

 DNSUpdater (QObject *parent=nullptr)
 
 ~DNSUpdater ()
 

Static Public Member Functions

static QUrl getRegistrationUrl (DNS::Service service)
 

Private Types

enum  State { OK , INVALID_CREDS , FATAL }
 

Private Slots

void checkPublicIP ()
 
void ipRequestFinished (const DownloadResult &result)
 
void updateDNSService ()
 
void ipUpdateFinished (const DownloadResult &result)
 

Private Member Functions

QString getUpdateUrl () const
 
void processIPUpdateReply (const QString &reply)
 

Private Attributes

QHostAddress m_lastIP
 
QDateTime m_lastIPCheckTime
 
QTimer m_ipCheckTimer
 
int m_state
 
DNS::Service m_service
 
QString m_domain
 
QString m_username
 
QString m_password
 

Static Private Attributes

static const int IP_CHECK_INTERVAL_MS = 1800000
 

Detailed Description

Definition at line 43 of file dnsupdater.h.

Member Enumeration Documentation

◆ State

enum Net::DNSUpdater::State
private
Enumerator
OK 
INVALID_CREDS 
FATAL 

Definition at line 63 of file dnsupdater.h.

64  {
65  OK,
67  FATAL
68  };

Constructor & Destructor Documentation

◆ DNSUpdater()

DNSUpdater::DNSUpdater ( QObject *  parent = nullptr)
explicit

Definition at line 41 of file dnsupdater.cpp.

42  : QObject(parent)
43  , m_state(OK)
45 {
47 
48  // Load saved settings from previous session
49  const Preferences *const pref = Preferences::instance();
51  m_lastIP = QHostAddress(pref->getDNSLastIP());
52 
53  // Start IP checking timer
55  connect(&m_ipCheckTimer, &QTimer::timeout, this, &DNSUpdater::checkPublicIP);
56  m_ipCheckTimer.start();
57 
58  // Check lastUpdate to avoid flooding
59  if (!m_lastIPCheckTime.isValid()
60  || (m_lastIPCheckTime.secsTo(QDateTime::currentDateTime()) * 1000 > IP_CHECK_INTERVAL_MS))
61  {
62  checkPublicIP();
63  }
64 }
void updateCredentials()
Definition: dnsupdater.cpp:238
QTimer m_ipCheckTimer
Definition: dnsupdater.h:77
QDateTime m_lastIPCheckTime
Definition: dnsupdater.h:76
QHostAddress m_lastIP
Definition: dnsupdater.h:75
DNS::Service m_service
Definition: dnsupdater.h:80
void checkPublicIP()
Definition: dnsupdater.cpp:74
static const int IP_CHECK_INTERVAL_MS
Definition: dnsupdater.h:70
static Preferences * instance()
QDateTime getDNSLastUpd() const
QString getDNSLastIP() const

References checkPublicIP(), Preferences::getDNSLastIP(), Preferences::getDNSLastUpd(), Preferences::instance(), IP_CHECK_INTERVAL_MS, m_ipCheckTimer, m_lastIP, m_lastIPCheckTime, and updateCredentials().

Here is the call graph for this function:

◆ ~DNSUpdater()

DNSUpdater::~DNSUpdater ( )

Definition at line 66 of file dnsupdater.cpp.

67 {
68  // Save lastupdate time and last ip
69  Preferences *const pref = Preferences::instance();
71  pref->setDNSLastIP(m_lastIP.toString());
72 }
void setDNSLastIP(const QString &ip)
void setDNSLastUpd(const QDateTime &date)

References Preferences::instance(), m_lastIP, m_lastIPCheckTime, Preferences::setDNSLastIP(), and Preferences::setDNSLastUpd().

Here is the call graph for this function:

Member Function Documentation

◆ checkPublicIP

void DNSUpdater::checkPublicIP ( )
privateslot

Definition at line 74 of file dnsupdater.cpp.

75 {
76  Q_ASSERT(m_state == OK);
77 
79  DownloadRequest("http://checkip.dyndns.org").userAgent("qBittorrent/" QBT_VERSION_2)
81 
82  m_lastIPCheckTime = QDateTime::currentDateTime();
83 }
void ipRequestFinished(const DownloadResult &result)
Definition: dnsupdater.cpp:85
DownloadHandler * download(const DownloadRequest &downloadRequest)
static DownloadManager * instance()

References Net::DownloadManager::download(), Net::DownloadManager::instance(), ipRequestFinished(), m_lastIPCheckTime, m_state, and OK.

Referenced by DNSUpdater(), and updateCredentials().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getRegistrationUrl()

QUrl DNSUpdater::getRegistrationUrl ( DNS::Service  service)
static

Definition at line 299 of file dnsupdater.cpp.

300 {
301  switch (service)
302  {
304  return {"https://account.dyn.com/entrance/"};
305  case DNS::Service::NoIP:
306  return {"https://www.noip.com/remote-access"};
307  default:
308  Q_ASSERT(false);
309  break;
310  }
311  return {};
312 }

References DNS::DynDNS, and DNS::NoIP.

Referenced by OptionsDialog::on_registerDNSBtn_clicked().

Here is the caller graph for this function:

◆ getUpdateUrl()

QString DNSUpdater::getUpdateUrl ( ) const
private

Definition at line 131 of file dnsupdater.cpp.

132 {
133  QUrl url;
134 #ifdef QT_NO_OPENSSL
135  url.setScheme("http");
136 #else
137  url.setScheme("https");
138 #endif
139  url.setUserName(m_username);
140  url.setPassword(m_password);
141 
142  Q_ASSERT(!m_lastIP.isNull());
143  // Service specific
144  switch (m_service)
145  {
147  url.setHost("members.dyndns.org");
148  break;
149  case DNS::Service::NoIP:
150  url.setHost("dynupdate.no-ip.com");
151  break;
152  default:
153  qWarning() << "Unrecognized Dynamic DNS service!";
154  Q_ASSERT(false);
155  break;
156  }
157  url.setPath("/nic/update");
158 
159  QUrlQuery urlQuery(url);
160  urlQuery.addQueryItem("hostname", m_domain);
161  urlQuery.addQueryItem("myip", m_lastIP.toString());
162  url.setQuery(urlQuery);
163  Q_ASSERT(url.isValid());
164 
165  qDebug() << Q_FUNC_INFO << url.toString();
166  return url.toString();
167 }
QString m_username
Definition: dnsupdater.h:82
QString m_password
Definition: dnsupdater.h:83
QString m_domain
Definition: dnsupdater.h:81

References DNS::DynDNS, m_domain, m_lastIP, m_password, m_service, m_username, and DNS::NoIP.

Referenced by updateDNSService().

Here is the caller graph for this function:

◆ ipRequestFinished

void DNSUpdater::ipRequestFinished ( const DownloadResult result)
privateslot

Definition at line 85 of file dnsupdater.cpp.

86 {
87  if (result.status != DownloadStatus::Success)
88  {
89  qWarning() << "IP request failed:" << result.errorString;
90  return;
91  }
92 
93  // Parse response
94  const QRegularExpressionMatch ipRegexMatch = QRegularExpression("Current IP Address:\\s+([^<]+)</body>").match(result.data);
95  if (ipRegexMatch.hasMatch())
96  {
97  QString ipStr = ipRegexMatch.captured(1);
98  qDebug() << Q_FUNC_INFO << "Regular expression captured the following IP:" << ipStr;
99  QHostAddress newIp(ipStr);
100  if (!newIp.isNull())
101  {
102  if (m_lastIP != newIp)
103  {
104  qDebug() << Q_FUNC_INFO << "The IP address changed, report the change to DynDNS...";
105  qDebug() << m_lastIP.toString() << "->" << newIp.toString();
106  m_lastIP = newIp;
108  }
109  }
110  else
111  {
112  qWarning() << Q_FUNC_INFO << "Failed to construct a QHostAddress from the IP string";
113  }
114  }
115  else
116  {
117  qWarning() << Q_FUNC_INFO << "Regular expression failed to capture the IP address";
118  }
119 }
void updateDNSService()
Definition: dnsupdater.cpp:121
DownloadStatus status

References Net::DownloadResult::data, Net::DownloadResult::errorString, m_lastIP, Net::DownloadResult::status, Net::Success, and updateDNSService().

Referenced by checkPublicIP().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipUpdateFinished

void DNSUpdater::ipUpdateFinished ( const DownloadResult result)
privateslot

Definition at line 169 of file dnsupdater.cpp.

170 {
171  if (result.status == DownloadStatus::Success)
172  processIPUpdateReply(result.data);
173  else
174  qWarning() << "IP update failed:" << result.errorString;
175 }
void processIPUpdateReply(const QString &reply)
Definition: dnsupdater.cpp:177

References Net::DownloadResult::data, Net::DownloadResult::errorString, processIPUpdateReply(), Net::DownloadResult::status, and Net::Success.

Referenced by updateDNSService().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ processIPUpdateReply()

void DNSUpdater::processIPUpdateReply ( const QString &  reply)
private

Definition at line 177 of file dnsupdater.cpp.

178 {
179  Logger *const logger = Logger::instance();
180  qDebug() << Q_FUNC_INFO << reply;
181  const QString code = reply.split(' ').first();
182  qDebug() << Q_FUNC_INFO << "Code:" << code;
183 
184  if ((code == "good") || (code == "nochg"))
185  {
186  logger->addMessage(tr("Your dynamic DNS was successfully updated."), Log::INFO);
187  return;
188  }
189 
190  if ((code == "911") || (code == "dnserr"))
191  {
192  logger->addMessage(tr("Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes."), Log::CRITICAL);
193  m_lastIP.clear();
194  // It will retry in 30 minutes because the timer was not stopped
195  return;
196  }
197 
198  // Everything below is an error, stop updating until the user updates something
199  m_ipCheckTimer.stop();
200  m_lastIP.clear();
201  if (code == "nohost")
202  {
203  logger->addMessage(tr("Dynamic DNS error: hostname supplied does not exist under specified account."), Log::CRITICAL);
205  return;
206  }
207 
208  if (code == "badauth")
209  {
210  logger->addMessage(tr("Dynamic DNS error: Invalid username/password."), Log::CRITICAL);
212  return;
213  }
214 
215  if (code == "badagent")
216  {
217  logger->addMessage(tr("Dynamic DNS error: qBittorrent was blacklisted by the service, please submit a bug report at http://bugs.qbittorrent.org."),
218  Log::CRITICAL);
219  m_state = FATAL;
220  return;
221  }
222 
223  if (code == "!donator")
224  {
225  logger->addMessage(tr("Dynamic DNS error: %1 was returned by the service, please submit a bug report at http://bugs.qbittorrent.org.").arg("!donator"),
226  Log::CRITICAL);
227  m_state = FATAL;
228  return;
229  }
230 
231  if (code == "abuse")
232  {
233  logger->addMessage(tr("Dynamic DNS error: Your username was blocked due to abuse."), Log::CRITICAL);
234  m_state = FATAL;
235  }
236 }
Definition: logger.h:73
void addMessage(const QString &message, const Log::MsgType &type=Log::NORMAL)
Definition: logger.cpp:73
static Logger * instance()
Definition: logger.cpp:56
@ CRITICAL
Definition: logger.h:48
@ INFO
Definition: logger.h:46

References Logger::addMessage(), Log::CRITICAL, FATAL, Log::INFO, Logger::instance(), INVALID_CREDS, m_ipCheckTimer, m_lastIP, and m_state.

Referenced by ipUpdateFinished().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateCredentials

void DNSUpdater::updateCredentials ( )
slot

Definition at line 238 of file dnsupdater.cpp.

239 {
240  if (m_state == FATAL) return;
241  Preferences *const pref = Preferences::instance();
242  Logger *const logger = Logger::instance();
243  bool change = false;
244  // Get DNS service information
245  if (m_service != pref->getDynDNSService())
246  {
247  m_service = pref->getDynDNSService();
248  change = true;
249  }
250  if (m_domain != pref->getDynDomainName())
251  {
252  m_domain = pref->getDynDomainName();
253  const QRegularExpressionMatch domainRegexMatch = QRegularExpression("^(?:(?!\\d|-)[a-zA-Z0-9\\-]{1,63}\\.)+[a-zA-Z]{2,}$").match(m_domain);
254  if (!domainRegexMatch.hasMatch())
255  {
256  logger->addMessage(tr("Dynamic DNS error: supplied domain name is invalid."), Log::CRITICAL);
257  m_lastIP.clear();
258  m_ipCheckTimer.stop();
260  return;
261  }
262  change = true;
263  }
264  if (m_username != pref->getDynDNSUsername())
265  {
266  m_username = pref->getDynDNSUsername();
267  if (m_username.length() < 4)
268  {
269  logger->addMessage(tr("Dynamic DNS error: supplied username is too short."), Log::CRITICAL);
270  m_lastIP.clear();
271  m_ipCheckTimer.stop();
273  return;
274  }
275  change = true;
276  }
277  if (m_password != pref->getDynDNSPassword())
278  {
279  m_password = pref->getDynDNSPassword();
280  if (m_password.length() < 4)
281  {
282  logger->addMessage(tr("Dynamic DNS error: supplied password is too short."), Log::CRITICAL);
283  m_lastIP.clear();
284  m_ipCheckTimer.stop();
286  return;
287  }
288  change = true;
289  }
290 
291  if ((m_state == INVALID_CREDS) && change)
292  {
293  m_state = OK; // Try again
294  m_ipCheckTimer.start();
295  checkPublicIP();
296  }
297 }
QString getDynDNSUsername() const
QString getDynDNSPassword() const
DNS::Service getDynDNSService() const
QString getDynDomainName() const

References Logger::addMessage(), checkPublicIP(), Log::CRITICAL, FATAL, Preferences::getDynDNSPassword(), Preferences::getDynDNSService(), Preferences::getDynDNSUsername(), Preferences::getDynDomainName(), Logger::instance(), Preferences::instance(), INVALID_CREDS, m_domain, m_ipCheckTimer, m_lastIP, m_password, m_service, m_state, m_username, and OK.

Referenced by DNSUpdater().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateDNSService

void DNSUpdater::updateDNSService ( )
privateslot

Definition at line 121 of file dnsupdater.cpp.

122 {
123  qDebug() << Q_FUNC_INFO;
124 
125  m_lastIPCheckTime = QDateTime::currentDateTime();
127  DownloadRequest(getUpdateUrl()).userAgent("qBittorrent/" QBT_VERSION_2)
129 }
QString getUpdateUrl() const
Definition: dnsupdater.cpp:131
void ipUpdateFinished(const DownloadResult &result)
Definition: dnsupdater.cpp:169

References Net::DownloadManager::download(), getUpdateUrl(), Net::DownloadManager::instance(), ipUpdateFinished(), and m_lastIPCheckTime.

Referenced by ipRequestFinished().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ IP_CHECK_INTERVAL_MS

const int Net::DNSUpdater::IP_CHECK_INTERVAL_MS = 1800000
staticprivate

Definition at line 70 of file dnsupdater.h.

Referenced by DNSUpdater().

◆ m_domain

QString Net::DNSUpdater::m_domain
private

Definition at line 81 of file dnsupdater.h.

Referenced by getUpdateUrl(), and updateCredentials().

◆ m_ipCheckTimer

QTimer Net::DNSUpdater::m_ipCheckTimer
private

Definition at line 77 of file dnsupdater.h.

Referenced by DNSUpdater(), processIPUpdateReply(), and updateCredentials().

◆ m_lastIP

QHostAddress Net::DNSUpdater::m_lastIP
private

◆ m_lastIPCheckTime

QDateTime Net::DNSUpdater::m_lastIPCheckTime
private

Definition at line 76 of file dnsupdater.h.

Referenced by checkPublicIP(), DNSUpdater(), updateDNSService(), and ~DNSUpdater().

◆ m_password

QString Net::DNSUpdater::m_password
private

Definition at line 83 of file dnsupdater.h.

Referenced by getUpdateUrl(), and updateCredentials().

◆ m_service

DNS::Service Net::DNSUpdater::m_service
private

Definition at line 80 of file dnsupdater.h.

Referenced by getUpdateUrl(), and updateCredentials().

◆ m_state

int Net::DNSUpdater::m_state
private

Definition at line 78 of file dnsupdater.h.

Referenced by checkPublicIP(), processIPUpdateReply(), and updateCredentials().

◆ m_username

QString Net::DNSUpdater::m_username
private

Definition at line 82 of file dnsupdater.h.

Referenced by getUpdateUrl(), and updateCredentials().


The documentation for this class was generated from the following files: