summaryrefslogtreecommitdiffstats
path: root/chromium/net/dns/mdns_client_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/dns/mdns_client_impl.cc')
-rw-r--r--chromium/net/dns/mdns_client_impl.cc143
1 files changed, 107 insertions, 36 deletions
diff --git a/chromium/net/dns/mdns_client_impl.cc b/chromium/net/dns/mdns_client_impl.cc
index c95b86c6d17..68cee7a87ec 100644
--- a/chromium/net/dns/mdns_client_impl.cc
+++ b/chromium/net/dns/mdns_client_impl.cc
@@ -26,6 +26,13 @@ namespace net {
namespace {
const unsigned MDnsTransactionTimeoutSeconds = 3;
+// The fractions of the record's original TTL after which an active listener
+// (one that had |SetActiveRefresh(true)| called) will send a query to refresh
+// its cache. This happens both at 85% of the original TTL and again at 95% of
+// the original TTL.
+const double kListenerRefreshRatio1 = 0.85;
+const double kListenerRefreshRatio2 = 0.95;
+const unsigned kMillisecondsPerSecond = 1000;
} // namespace
@@ -192,10 +199,10 @@ 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.";
+ DVLOG(1) << "Could not understand an mDNS packet.";
return; // Message is unreadable.
}
@@ -213,10 +220,10 @@ void MDnsClientImpl::Core::HandlePacket(DnsResponse* response,
&parser, base::Time::Now());
if (!record) {
- LOG(WARNING) << "Could not understand an mDNS record.";
+ DVLOG(1) << "Could not understand an mDNS record.";
if (offset == parser.GetOffset()) {
- LOG(WARNING) << "Abandoned parsing the rest of the packet.";
+ DVLOG(1) << "Abandoned parsing the rest of the packet.";
return; // The parser did not advance, abort reading the packet.
} else {
continue; // We may be able to extract other records from the packet.
@@ -225,7 +232,7 @@ void MDnsClientImpl::Core::HandlePacket(DnsResponse* response,
if ((record->klass() & dns_protocol::kMDnsClassMask) !=
dns_protocol::kClassIN) {
- LOG(WARNING) << "Received an mDNS record with non-IN class. Ignoring.";
+ DVLOG(1) << "Received an mDNS record with non-IN class. Ignoring.";
continue; // Ignore all records not in the IN class.
}
@@ -235,29 +242,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 +299,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 +380,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 +437,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 +458,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 +478,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_ = record->time_created();
+
+ 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 +519,47 @@ void MDnsListenerImpl::AlertNsecRecord() {
delegate_->OnNsecRecord(name_, rrtype_);
}
+void MDnsListenerImpl::ScheduleNextRefresh() {
+ DCHECK(last_update_ != base::Time());
+
+ if (!active_refresh_)
+ return;
+
+ // 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()));
+
+ // Schedule refreshes at both 85% and 95% of the original TTL. These will both
+ // be canceled and rescheduled if the record's TTL is updated due to a
+ // response being received.
+ base::Time next_refresh1 = last_update_ + base::TimeDelta::FromMilliseconds(
+ static_cast<int>(kMillisecondsPerSecond *
+ kListenerRefreshRatio1 * ttl_));
+
+ base::Time next_refresh2 = last_update_ + base::TimeDelta::FromMilliseconds(
+ static_cast<int>(kMillisecondsPerSecond *
+ kListenerRefreshRatio2 * 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,