mirror of https://github.com/procxx/kepka.git
				
				
				
			Fix possible crash in DomainResolver.
App::CallDelayed() could be queued twice for a single key, if before the delayed call we cleared entry in _attempts and created it again.
This commit is contained in:
		
							parent
							
								
									8acd47bf2f
								
							
						
					
					
						commit
						a59353df9f
					
				|  | @ -453,7 +453,7 @@ void DomainResolver::resolve(const AttemptKey &key) { | ||||||
| 	auto hosts = DnsDomains(); | 	auto hosts = DnsDomains(); | ||||||
| 	std::random_device rd; | 	std::random_device rd; | ||||||
| 	ranges::shuffle(hosts, std::mt19937(rd())); | 	ranges::shuffle(hosts, std::mt19937(rd())); | ||||||
| 	_attempts.emplace(key, std::move(hosts)); | 	_attempts.emplace(key, Attempts{ std::move(hosts) }); | ||||||
| 	sendNextRequest(key); | 	sendNextRequest(key); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -478,12 +478,13 @@ void DomainResolver::sendNextRequest(const AttemptKey &key) { | ||||||
| 	if (i == end(_attempts)) { | 	if (i == end(_attempts)) { | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	auto &hosts = i->second; | 	auto &attempts = i->second; | ||||||
|  | 	auto &hosts = attempts.hosts; | ||||||
| 	const auto host = hosts.back(); | 	const auto host = hosts.back(); | ||||||
| 	hosts.pop_back(); | 	hosts.pop_back(); | ||||||
| 
 | 
 | ||||||
| 	if (!hosts.empty()) { | 	if (!hosts.empty()) { | ||||||
| 		App::CallDelayed(kSendNextTimeout, this, [=] { | 		App::CallDelayed(kSendNextTimeout, &attempts.guard, [=] { | ||||||
| 			sendNextRequest(key); | 			sendNextRequest(key); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -91,6 +91,11 @@ private: | ||||||
| 		QStringList ips; | 		QStringList ips; | ||||||
| 		crl::time expireAt = 0; | 		crl::time expireAt = 0; | ||||||
| 
 | 
 | ||||||
|  | 	}; | ||||||
|  | 	struct Attempts { | ||||||
|  | 		std::vector<QString> hosts; | ||||||
|  | 		base::has_weak_ptr guard; | ||||||
|  | 
 | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	void resolve(const AttemptKey &key); | 	void resolve(const AttemptKey &key); | ||||||
|  | @ -110,7 +115,7 @@ private: | ||||||
| 		crl::time expireAt)> _callback; | 		crl::time expireAt)> _callback; | ||||||
| 
 | 
 | ||||||
| 	QNetworkAccessManager _manager; | 	QNetworkAccessManager _manager; | ||||||
| 	std::map<AttemptKey, std::vector<QString>> _attempts; | 	std::map<AttemptKey, Attempts> _attempts; | ||||||
| 	std::map<AttemptKey, std::vector<ServiceWebRequest>> _requests; | 	std::map<AttemptKey, std::vector<ServiceWebRequest>> _requests; | ||||||
| 	std::map<AttemptKey, CacheEntry> _cache; | 	std::map<AttemptKey, CacheEntry> _cache; | ||||||
| 	crl::time _lastTimestamp = 0; | 	crl::time _lastTimestamp = 0; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue