Skip to content

Commit 2c5a352

Browse files
committed
Reduce hosts file parsing warnings
Closes #361
1 parent 3efb25e commit 2c5a352

1 file changed

Lines changed: 35 additions & 7 deletions

File tree

src/main/java/org/xbill/DNS/hosts/HostsFileParser.java

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.util.Map;
1515
import java.util.Objects;
1616
import java.util.Optional;
17+
import java.util.concurrent.atomic.AtomicInteger;
1718
import lombok.RequiredArgsConstructor;
1819
import lombok.extern.slf4j.Slf4j;
1920
import org.xbill.DNS.Address;
@@ -37,6 +38,7 @@ public final class HostsFileParser {
3738
private final boolean clearCacheOnChange;
3839
private Instant lastFileReadTime = Instant.MIN;
3940
private boolean isEntireFileParsed;
41+
private boolean hostsFileWarningLogged = false;
4042

4143
/**
4244
* Creates a new instance based on the current OS's default. Unix and alike (or rather everything
@@ -116,9 +118,11 @@ public synchronized Optional<InetAddress> getAddressForHost(Name name, int type)
116118
private void parseEntireHostsFile() throws IOException {
117119
String line;
118120
int lineNumber = 0;
121+
AtomicInteger addressFailures = new AtomicInteger(0);
122+
AtomicInteger nameFailures = new AtomicInteger(0);
119123
try (BufferedReader hostsReader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
120124
while ((line = hostsReader.readLine()) != null) {
121-
LineData lineData = parseLine(++lineNumber, line);
125+
LineData lineData = parseLine(++lineNumber, line, addressFailures, nameFailures);
122126
if (lineData != null) {
123127
for (Name lineName : lineData.names) {
124128
InetAddress lineAddress =
@@ -129,15 +133,26 @@ private void parseEntireHostsFile() throws IOException {
129133
}
130134
}
131135

136+
if (!hostsFileWarningLogged && (addressFailures.get() > 0 || nameFailures.get() > 0)) {
137+
log.warn(
138+
"Failed to parse entire hosts file {}, address failures={}, name failures={}",
139+
path,
140+
addressFailures.get(),
141+
nameFailures);
142+
hostsFileWarningLogged = true;
143+
}
144+
132145
isEntireFileParsed = true;
133146
}
134147

135148
private void searchHostsFileForEntry(Name name, int type) throws IOException {
136149
String line;
137150
int lineNumber = 0;
151+
AtomicInteger addressFailures = new AtomicInteger(0);
152+
AtomicInteger nameFailures = new AtomicInteger(0);
138153
try (BufferedReader hostsReader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
139154
while ((line = hostsReader.readLine()) != null) {
140-
LineData lineData = parseLine(++lineNumber, line);
155+
LineData lineData = parseLine(++lineNumber, line, addressFailures, nameFailures);
141156
if (lineData != null) {
142157
for (Name lineName : lineData.names) {
143158
boolean isSearchedEntry = lineName.equals(name);
@@ -151,6 +166,16 @@ private void searchHostsFileForEntry(Name name, int type) throws IOException {
151166
}
152167
}
153168
}
169+
170+
if (!hostsFileWarningLogged && (addressFailures.get() > 0 || nameFailures.get() > 0)) {
171+
log.warn(
172+
"Failed to find {} in hosts file {}, address failures={}, name failures={}",
173+
name,
174+
path,
175+
addressFailures.get(),
176+
nameFailures);
177+
hostsFileWarningLogged = true;
178+
}
154179
}
155180

156181
@RequiredArgsConstructor
@@ -160,7 +185,8 @@ private static final class LineData {
160185
final Iterable<? extends Name> names;
161186
}
162187

163-
private LineData parseLine(int lineNumber, String line) {
188+
private LineData parseLine(
189+
int lineNumber, String line, AtomicInteger addressFailures, AtomicInteger nameFailures) {
164190
String[] lineTokens = getLineTokens(line);
165191
if (lineTokens.length < 2) {
166192
return null;
@@ -174,24 +200,26 @@ private LineData parseLine(int lineNumber, String line) {
174200
}
175201

176202
if (lineAddressBytes == null) {
177-
log.warn("Could not decode address {}, {}#L{}", lineTokens[0], path, lineNumber);
203+
log.debug("Could not decode address {}, {}#L{}", lineTokens[0], path, lineNumber);
204+
addressFailures.incrementAndGet();
178205
return null;
179206
}
180207

181208
Iterable<? extends Name> lineNames =
182209
Arrays.stream(lineTokens)
183210
.skip(1)
184-
.map(lineTokenName -> safeName(lineTokenName, lineNumber))
211+
.map(lineTokenName -> safeName(lineTokenName, lineNumber, nameFailures))
185212
.filter(Objects::nonNull)
186213
::iterator;
187214
return new LineData(lineAddressType, lineAddressBytes, lineNames);
188215
}
189216

190-
private Name safeName(String name, int lineNumber) {
217+
private Name safeName(String name, int lineNumber, AtomicInteger nameFailures) {
191218
try {
192219
return Name.fromString(name, Name.root);
193220
} catch (TextParseException e) {
194-
log.warn("Could not decode name {}, {}#L{}, skipping", name, path, lineNumber);
221+
log.debug("Could not decode name {}, {}#L{}, skipping", name, path, lineNumber);
222+
nameFailures.incrementAndGet();
195223
return null;
196224
}
197225
}

0 commit comments

Comments
 (0)