1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 /** 6 * This view displays information on the host resolver: 7 * 8 * - Shows the default address family. 9 * - Has a button to enable IPv6, if it is disabled. 10 * - Shows the current host cache contents. 11 * - Has a button to clear the host cache. 12 * - Shows the parameters used to construct the host cache (capacity, ttl). 13 */ 14 15 // TODO(mmenke): Add links for each address entry to the corresponding NetLog 16 // source. This could either be done by adding NetLog source ids 17 // to cache entries, or tracking sources based on their type and 18 // description. Former is simpler, latter may be useful 19 // elsewhere as well. 20 var DnsView = (function() { 21 'use strict'; 22 23 // We inherit from DivView. 24 var superClass = DivView; 25 26 /** 27 * @constructor 28 */ 29 function DnsView() { 30 assertFirstConstructorCall(DnsView); 31 32 // Call superclass's constructor. 33 superClass.call(this, DnsView.MAIN_BOX_ID); 34 35 $(DnsView.ENABLE_IPV6_BUTTON_ID).onclick = 36 g_browser.enableIPv6.bind(g_browser); 37 $(DnsView.CLEAR_CACHE_BUTTON_ID).onclick = 38 g_browser.sendClearHostResolverCache.bind(g_browser); 39 40 // Register to receive changes to the host resolver info. 41 g_browser.addHostResolverInfoObserver(this, false); 42 } 43 44 DnsView.TAB_ID = 'tab-handle-dns'; 45 DnsView.TAB_NAME = 'DNS'; 46 DnsView.TAB_HASH = '#dns'; 47 48 // IDs for special HTML elements in dns_view.html 49 DnsView.MAIN_BOX_ID = 'dns-view-tab-content'; 50 DnsView.DEFAULT_FAMILY_SPAN_ID = 'dns-view-default-family'; 51 DnsView.IPV6_DISABLED_SPAN_ID = 'dns-view-ipv6-disabled'; 52 DnsView.ENABLE_IPV6_BUTTON_ID = 'dns-view-enable-ipv6'; 53 54 DnsView.INTERNAL_DNS_ENABLED_SPAN_ID = 'dns-view-internal-dns-enabled'; 55 DnsView.INTERNAL_DNS_INVALID_CONFIG_SPAN_ID = 56 'dns-view-internal-dns-invalid-config'; 57 DnsView.INTERNAL_DNS_CONFIG_TBODY_ID = 'dns-view-internal-dns-config-tbody'; 58 59 DnsView.CLEAR_CACHE_BUTTON_ID = 'dns-view-clear-cache'; 60 DnsView.CAPACITY_SPAN_ID = 'dns-view-cache-capacity'; 61 62 DnsView.ACTIVE_SPAN_ID = 'dns-view-cache-active'; 63 DnsView.EXPIRED_SPAN_ID = 'dns-view-cache-expired'; 64 DnsView.CACHE_TBODY_ID = 'dns-view-cache-tbody'; 65 66 cr.addSingletonGetter(DnsView); 67 68 DnsView.prototype = { 69 // Inherit the superclass's methods. 70 __proto__: superClass.prototype, 71 72 onLoadLogFinish: function(data) { 73 return this.onHostResolverInfoChanged(data.hostResolverInfo); 74 }, 75 76 onHostResolverInfoChanged: function(hostResolverInfo) { 77 // Clear the existing values. 78 $(DnsView.DEFAULT_FAMILY_SPAN_ID).innerHTML = ''; 79 $(DnsView.CAPACITY_SPAN_ID).innerHTML = ''; 80 $(DnsView.CACHE_TBODY_ID).innerHTML = ''; 81 $(DnsView.ACTIVE_SPAN_ID).innerHTML = '0'; 82 $(DnsView.EXPIRED_SPAN_ID).innerHTML = '0'; 83 84 // Update fields containing async DNS configuration information. 85 displayAsyncDnsConfig_(hostResolverInfo); 86 87 // No info. 88 if (!hostResolverInfo || !hostResolverInfo.cache) 89 return false; 90 91 var family = hostResolverInfo.default_address_family; 92 addTextNode($(DnsView.DEFAULT_FAMILY_SPAN_ID), 93 addressFamilyToString(family)); 94 95 var ipv6Disabled = (family == AddressFamily.ADDRESS_FAMILY_IPV4); 96 setNodeDisplay($(DnsView.IPV6_DISABLED_SPAN_ID), ipv6Disabled); 97 98 // Fill in the basic cache information. 99 var hostResolverCache = hostResolverInfo.cache; 100 $(DnsView.CAPACITY_SPAN_ID).innerText = hostResolverCache.capacity; 101 102 var expiredEntries = 0; 103 // Date the cache was logged. This will be either now, when actively 104 // logging data, or the date the log dump was created. 105 var logDate; 106 if (MainView.isViewingLoadedLog()) { 107 logDate = new Date(ClientInfo.numericDate); 108 } else { 109 logDate = new Date(); 110 } 111 112 // Fill in the cache contents table. 113 for (var i = 0; i < hostResolverCache.entries.length; ++i) { 114 var e = hostResolverCache.entries[i]; 115 var tr = addNode($(DnsView.CACHE_TBODY_ID), 'tr'); 116 117 var hostnameCell = addNode(tr, 'td'); 118 addTextNode(hostnameCell, e.hostname); 119 120 var familyCell = addNode(tr, 'td'); 121 addTextNode(familyCell, 122 addressFamilyToString(e.address_family)); 123 124 var addressesCell = addNode(tr, 'td'); 125 126 if (e.error != undefined) { 127 var errorText = 128 e.error + ' (' + netErrorToString(e.error) + ')'; 129 var errorNode = addTextNode(addressesCell, 'error: ' + errorText); 130 addressesCell.classList.add('warning-text'); 131 } else { 132 addListToNode_(addNode(addressesCell, 'div'), e.addresses); 133 } 134 135 var expiresDate = timeutil.convertTimeTicksToDate(e.expiration); 136 var expiresCell = addNode(tr, 'td'); 137 timeutil.addNodeWithDate(expiresCell, expiresDate); 138 if (logDate > timeutil.convertTimeTicksToDate(e.expiration)) { 139 ++expiredEntries; 140 var expiredSpan = addNode(expiresCell, 'span'); 141 expiredSpan.classList.add('warning-text'); 142 addTextNode(expiredSpan, ' [Expired]'); 143 } 144 } 145 146 $(DnsView.ACTIVE_SPAN_ID).innerText = 147 hostResolverCache.entries.length - expiredEntries; 148 $(DnsView.EXPIRED_SPAN_ID).innerText = expiredEntries; 149 return true; 150 }, 151 }; 152 153 /** 154 * Displays information corresponding to the current async DNS configuration. 155 * @param {Object} hostResolverInfo The host resolver information. 156 */ 157 function displayAsyncDnsConfig_(hostResolverInfo) { 158 // Clear the table. 159 $(DnsView.INTERNAL_DNS_CONFIG_TBODY_ID).innerHTML = ''; 160 161 // Figure out if the internal DNS resolver is disabled or has no valid 162 // configuration information, and update display accordingly. 163 var enabled = hostResolverInfo && 164 hostResolverInfo.dns_config !== undefined; 165 var noConfig = enabled && 166 hostResolverInfo.dns_config.nameservers === undefined; 167 $(DnsView.INTERNAL_DNS_ENABLED_SPAN_ID).innerText = enabled; 168 setNodeDisplay($(DnsView.INTERNAL_DNS_INVALID_CONFIG_SPAN_ID), noConfig); 169 170 // If the internal DNS resolver is disabled or has no valid configuration, 171 // we're done. 172 if (!enabled || noConfig) 173 return; 174 175 var dnsConfig = hostResolverInfo.dns_config; 176 177 // Display nameservers first. 178 var nameserverRow = addNode($(DnsView.INTERNAL_DNS_CONFIG_TBODY_ID), 'tr'); 179 addNodeWithText(nameserverRow, 'th', 'nameservers'); 180 addListToNode_(addNode(nameserverRow, 'td'), dnsConfig.nameservers); 181 182 // Add everything else in |dnsConfig| to the table. 183 for (var key in dnsConfig) { 184 if (key == 'nameservers') 185 continue; 186 var tr = addNode($(DnsView.INTERNAL_DNS_CONFIG_TBODY_ID), 'tr'); 187 addNodeWithText(tr, 'th', key); 188 var td = addNode(tr, 'td'); 189 190 // For lists, display each list entry on a separate line. 191 if (typeof dnsConfig[key] == 'object' && 192 dnsConfig[key].constructor == Array) { 193 addListToNode_(td, dnsConfig[key]); 194 continue; 195 } 196 197 addTextNode(td, dnsConfig[key]); 198 } 199 } 200 201 /** 202 * Takes a last of strings and adds them all to a DOM node, displaying them 203 * on separate lines. 204 * @param {DomNode} node The parent node. 205 * @param {Array.<string>} list List of strings to add to the node. 206 */ 207 function addListToNode_(node, list) { 208 for (var i = 0; i < list.length; ++i) 209 addNodeWithText(node, 'div', list[i]); 210 } 211 212 return DnsView; 213 })(); 214