Index: net/dns/mdns_client_impl.cc |
diff --git a/net/dns/mdns_client_impl.cc b/net/dns/mdns_client_impl.cc |
index c95b86c6d1735e610fd46beafc3c51c9939f0c56..b64ffa4e1151e3e03062ff7270dc2916aadfb18d 100644 |
--- a/net/dns/mdns_client_impl.cc |
+++ b/net/dns/mdns_client_impl.cc |
@@ -26,6 +26,9 @@ namespace net { |
namespace { |
const unsigned MDnsTransactionTimeoutSeconds = 3; |
+const double kListenerRefreshPercentage1 = 0.85; |
szym
2014/01/23 11:24:03
Percentage suggests that this is divided by 100, i
Noam Samuel
2014/01/23 17:50:42
The time is relative to the record's original TTL,
|
+const double kListenerRefreshPercentage2 = 0.95; |
+const unsigned kMillisecondsPerSecond = 1000; |
} // namespace |
@@ -192,7 +195,7 @@ void MDnsClientImpl::Core::HandlePacket(DnsResponse* response, |
// Note: We store cache keys rather than record pointers to avoid |
// erroneous behavior in case a packet contains multiple exclusive |
// records with the same type and name. |
- std::map<MDnsCache::Key, MDnsListener::UpdateType> update_keys; |
+ std::map<MDnsCache::Key, MDnsCache::UpdateType> update_keys; |
if (!response->InitParseWithoutQuery(bytes_read)) { |
LOG(WARNING) << "Could not understand an mDNS packet."; |
@@ -235,29 +238,10 @@ void MDnsClientImpl::Core::HandlePacket(DnsResponse* response, |
// Cleanup time may have changed. |
ScheduleCleanup(cache_.next_expiration()); |
- if (update != MDnsCache::NoChange) { |
- MDnsListener::UpdateType update_external; |
- |
- switch (update) { |
- case MDnsCache::RecordAdded: |
- update_external = MDnsListener::RECORD_ADDED; |
- break; |
- case MDnsCache::RecordChanged: |
- update_external = MDnsListener::RECORD_CHANGED; |
- break; |
- case MDnsCache::NoChange: |
- default: |
- NOTREACHED(); |
- // Dummy assignment to suppress compiler warning. |
- update_external = MDnsListener::RECORD_CHANGED; |
- break; |
- } |
- |
- update_keys.insert(std::make_pair(update_key, update_external)); |
- } |
+ update_keys.insert(std::make_pair(update_key, update)); |
} |
- for (std::map<MDnsCache::Key, MDnsListener::UpdateType>::iterator i = |
+ for (std::map<MDnsCache::Key, MDnsCache::UpdateType>::iterator i = |
update_keys.begin(); i != update_keys.end(); i++) { |
const RecordParsed* record = cache_.LookupKey(i->first); |
if (!record) |
@@ -311,14 +295,14 @@ void MDnsClientImpl::Core::OnConnectionError(int error) { |
} |
void MDnsClientImpl::Core::AlertListeners( |
- MDnsListener::UpdateType update_type, |
+ MDnsCache::UpdateType update_type, |
const ListenerKey& key, |
const RecordParsed* record) { |
ListenerMap::iterator listener_map_iterator = listeners_.find(key); |
if (listener_map_iterator == listeners_.end()) return; |
FOR_EACH_OBSERVER(MDnsListenerImpl, *listener_map_iterator->second, |
- AlertDelegate(update_type, record)); |
+ HandleRecordUpdate(update_type, record)); |
} |
void MDnsClientImpl::Core::AddListener( |
@@ -392,7 +376,7 @@ void MDnsClientImpl::Core::DoCleanup() { |
void MDnsClientImpl::Core::OnRecordRemoved( |
const RecordParsed* record) { |
- AlertListeners(MDnsListener::RECORD_REMOVED, |
+ AlertListeners(MDnsCache::RecordRemoved, |
ListenerKey(record->name(), record->type()), record); |
} |
@@ -449,7 +433,14 @@ MDnsListenerImpl::MDnsListenerImpl( |
MDnsListener::Delegate* delegate, |
MDnsClientImpl* client) |
: rrtype_(rrtype), name_(name), client_(client), delegate_(delegate), |
- started_(false) { |
+ started_(false), active_refresh_(false) { |
+} |
+ |
+MDnsListenerImpl::~MDnsListenerImpl() { |
+ if (started_) { |
+ DCHECK(client_->core()); |
+ client_->core()->RemoveListener(this); |
+ } |
} |
bool MDnsListenerImpl::Start() { |
@@ -463,10 +454,15 @@ bool MDnsListenerImpl::Start() { |
return true; |
} |
-MDnsListenerImpl::~MDnsListenerImpl() { |
+void MDnsListenerImpl::SetActiveRefresh(bool active_refresh) { |
+ active_refresh_ = active_refresh; |
+ |
if (started_) { |
- DCHECK(client_->core()); |
- client_->core()->RemoveListener(this); |
+ if (!active_refresh_) { |
+ next_refresh_.Cancel(); |
+ } else if (last_update_ != base::Time()) { |
+ ScheduleNextRefresh(); |
+ } |
} |
} |
@@ -478,10 +474,40 @@ uint16 MDnsListenerImpl::GetType() const { |
return rrtype_; |
} |
-void MDnsListenerImpl::AlertDelegate(MDnsListener::UpdateType update_type, |
- const RecordParsed* record) { |
+void MDnsListenerImpl::HandleRecordUpdate(MDnsCache::UpdateType update_type, |
+ const RecordParsed* record) { |
DCHECK(started_); |
- delegate_->OnRecordUpdate(update_type, record); |
+ |
+ if (update_type != MDnsCache::RecordRemoved) { |
+ ttl_ = record->ttl(); |
+ last_update_ = base::Time::Now(); |
+ |
+ ScheduleNextRefresh(); |
+ } |
+ |
+ if (update_type != MDnsCache::NoChange) { |
+ MDnsListener::UpdateType update_external; |
+ |
+ switch (update_type) { |
+ case MDnsCache::RecordAdded: |
+ update_external = MDnsListener::RECORD_ADDED; |
+ break; |
+ case MDnsCache::RecordChanged: |
+ update_external = MDnsListener::RECORD_CHANGED; |
+ break; |
+ case MDnsCache::RecordRemoved: |
+ update_external = MDnsListener::RECORD_REMOVED; |
+ break; |
+ case MDnsCache::NoChange: |
+ default: |
+ NOTREACHED(); |
+ // Dummy assignment to suppress compiler warning. |
+ update_external = MDnsListener::RECORD_CHANGED; |
+ break; |
+ } |
+ |
+ delegate_->OnRecordUpdate(update_external, record); |
+ } |
} |
void MDnsListenerImpl::AlertNsecRecord() { |
@@ -489,6 +515,41 @@ void MDnsListenerImpl::AlertNsecRecord() { |
delegate_->OnNsecRecord(name_, rrtype_); |
} |
+void MDnsListenerImpl::ScheduleNextRefresh() { |
szym
2014/01/23 11:24:03
This function silently assumes that if active_refr
Noam Samuel
2014/01/23 17:50:42
Done.
|
+ if (active_refresh_) { |
szym
2014/01/23 11:24:03
By convention this should be:
if (!active_refresh_
Noam Samuel
2014/01/23 17:50:42
Done.
|
+ // A zero TTL is a goodbye packet and should not be refreshed. |
+ if (ttl_ == 0) { |
+ next_refresh_.Cancel(); |
+ return; |
+ } |
+ |
+ next_refresh_.Reset(base::Bind(&MDnsListenerImpl::DoRefresh, |
+ AsWeakPtr())); |
+ |
+ base::Time next_refresh1 = last_update_ + base::TimeDelta::FromMilliseconds( |
+ static_cast<int>(kMillisecondsPerSecond * |
+ kListenerRefreshPercentage1 * ttl_)); |
+ |
+ base::Time next_refresh2 = last_update_ + base::TimeDelta::FromMilliseconds( |
szym
2014/01/23 11:24:03
You need a comment somewhere why two refresh tasks
Noam Samuel
2014/01/23 17:50:42
Done.
|
+ static_cast<int>(kMillisecondsPerSecond * |
+ kListenerRefreshPercentage2 * ttl_)); |
+ |
+ base::MessageLoop::current()->PostDelayedTask( |
+ FROM_HERE, |
+ next_refresh_.callback(), |
+ next_refresh1 - base::Time::Now()); |
+ |
+ base::MessageLoop::current()->PostDelayedTask( |
+ FROM_HERE, |
+ next_refresh_.callback(), |
+ next_refresh2 - base::Time::Now()); |
+ } |
+} |
+ |
+void MDnsListenerImpl::DoRefresh() { |
+ client_->core()->SendQuery(rrtype_, name_); |
+} |
+ |
MDnsTransactionImpl::MDnsTransactionImpl( |
uint16 rrtype, |
const std::string& name, |