diff --git a/server/monitor-types/dns.js b/server/monitor-types/dns.js
index 56565e8af..8b833bd1d 100644
--- a/server/monitor-types/dns.js
+++ b/server/monitor-types/dns.js
@@ -4,7 +4,11 @@ const dayjs = require("dayjs");
const { dnsResolve } = require("../util-server");
const { R } = require("redbean-node");
const { ConditionVariable } = require("../monitor-conditions/variables");
-const { defaultStringOperators, defaultNumberOperators, defaultArrayOperators } = require("../monitor-conditions/operators");
+const {
+ defaultStringOperators,
+ defaultNumberOperators,
+ defaultArrayOperators
+} = require("../monitor-conditions/operators");
const { ConditionExpressionGroup } = require("../monitor-conditions/expression");
const { evaluateExpressionGroup } = require("../monitor-conditions/evaluator");
@@ -14,9 +18,9 @@ class DnsMonitorType extends MonitorType {
supportsConditions = true;
conditionVariables = [
- // A, AAAA, TXT, PTR, NS
+ // A, AAAA, TXT, NS
new ConditionVariable("records", defaultArrayOperators),
- // CNAME
+ // PTR, CNAME
new ConditionVariable("hostname", defaultStringOperators),
// CAA
new ConditionVariable("flags", defaultStringOperators),
@@ -43,10 +47,11 @@ class DnsMonitorType extends MonitorType {
name: monitor.hostname,
rrtype: monitor.dnsResolveType,
dnssec: true, // Request DNSSEC information in the response
- dnssecCheckingDisabled: monitor.skip_remote_dnssec,
+ dnssecCheckingDisabled: monitor.skipRemoteDnssec,
};
const transportData = {
type: monitor.dnsTransport,
+ timeout: monitor.timeout,
ignoreCertErrors: monitor.ignoreTls,
dohQueryPath: monitor.dohQueryPath,
dohUsePost: monitor.method === "POST",
@@ -62,32 +67,37 @@ class DnsMonitorType extends MonitorType {
const conditions = ConditionExpressionGroup.fromMonitor(monitor);
let conditionsResult = true;
const handleConditions = (data) => conditions ? evaluateExpressionGroup(conditions, data) : true;
-
- const records = dnsRes.answers.reduce((results, record) => {
+ const checkRecord = (results, record) => {
// Omit records that are not the same as the requested rrtype
if (record.type === monitor.dnsResolveType) {
+ // Add the record to the array
results.push(Buffer.isBuffer(record.data) ? record.data.toString() : record.data);
}
return results;
- }, []);
+ };
+
+ const records = dnsRes.answers.reduce(checkRecord, []);
// Return down status if no records are provided
if (records.length === 0) {
- rrtype = null;
- dnsMessage = "No records found";
- conditionsResult = false;
-
+ if (dnsRes.authorities.map(auth => auth.type).includes(monitor.dnsResolveType)) {
+ records.push(...dnsRes.authorities.reduce(checkRecord, []));
+ } else {
+ rrtype = null;
+ dnsMessage = "No records found";
+ conditionsResult = false;
+ }
}
switch (rrtype) {
case "A":
case "AAAA":
case "TXT":
- case "PTR":
case "NS":
dnsMessage = records.join(" | ");
conditionsResult = handleConditions({ records: records });
break;
+ case "PTR":
case "CNAME":
dnsMessage = records[0];
conditionsResult = handleConditions({ hostname: records[0].value });
@@ -134,7 +144,7 @@ class DnsMonitorType extends MonitorType {
break;
}
- if (monitor.dnsLastResult !== dnsMessage && dnsMessage !== undefined) {
+ if (monitor.dnsLastResult !== dnsMessage && dnsMessage !== undefined && monitor.id !== undefined) {
await R.exec("UPDATE `monitor` SET dns_last_result = ? WHERE id = ? ", [ dnsMessage, monitor.id ]);
}
diff --git a/server/util-server.js b/server/util-server.js
index 77c3ebe44..f3542b934 100644
--- a/server/util-server.js
+++ b/server/util-server.js
@@ -521,6 +521,8 @@ exports.dnsResolve = function (opts, resolverServer, resolverPort, transport) {
client.on("error", (err) => {
if (err.code === "ETIMEDOUT") {
err.message = `Connection to ${socketName} timed out`;
+ } else if (err.code === "ECONNREFUSED") {
+ err.message = `Connection to ${socketName} refused`;
}
reject(err);
});
@@ -638,7 +640,15 @@ exports.dnsResolve = function (opts, resolverServer, resolverPort, transport) {
});
const req = client.request(headers);
req.on("error", (err) => {
- err.message = "HTTP/2: " + err.message;
+ if (err.cause.code === "ETIMEDOUT") {
+ err = err.cause;
+ err.message = `Connection to ${socketName} timed out`;
+ } else if (err.cause.code === "ECONNREFUSED") {
+ err = err.cause;
+ err.message = `Connection to ${socketName} refused`;
+ } else {
+ err.message = "HTTP/2: " + err.message;
+ }
reject(err);
});
req.on("response", (resHeaders) => {
@@ -670,6 +680,11 @@ exports.dnsResolve = function (opts, resolverServer, resolverPort, transport) {
client.end();
}
client.on("error", (err) => {
+ if (err.code === "ETIMEDOUT") {
+ err.message = `Connection to ${socketName} timed out`;
+ } else if (err.code === "ECONNREFUSED") {
+ err.message = `Connection to ${socketName} refused`;
+ }
reject(err);
});
client.on("close", () => {
diff --git a/src/assets/app.scss b/src/assets/app.scss
index 6ddc99dec..5d6050b87 100644
--- a/src/assets/app.scss
+++ b/src/assets/app.scss
@@ -629,6 +629,10 @@ $shadow-box-padding: 20px;
}
}
+#doh-method {
+ width: 90px;
+}
+
@media (max-width: 770px) {
.toast-container {
margin-bottom: 100px !important;
diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue
index d6b3d11a7..817b71f53 100644
--- a/src/pages/EditMonitor.vue
+++ b/src/pages/EditMonitor.vue
@@ -371,38 +371,16 @@