From 4bd775e4bef9a049fb38d574a53aedc924e55800 Mon Sep 17 00:00:00 2001
From: filippolauria <filippo.lauria@iit.cnr.it>
Date: Fri, 31 Jan 2025 14:08:07 +0100
Subject: [PATCH] added advanced ping options to server and monitor and also
 added validation using ping MIN/MAX constants in monitor

---
 server/model/monitor.js | 33 ++++++++++++++++++++++++++++++++-
 server/server.js        |  6 ++++++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/server/model/monitor.js b/server/model/monitor.js
index 3ad8cfafc..67c295f68 100644
--- a/server/model/monitor.js
+++ b/server/model/monitor.js
@@ -2,7 +2,8 @@ const dayjs = require("dayjs");
 const axios = require("axios");
 const { Prometheus } = require("../prometheus");
 const { log, UP, DOWN, PENDING, MAINTENANCE, flipStatus, MAX_INTERVAL_SECOND, MIN_INTERVAL_SECOND,
-    SQL_DATETIME_FORMAT, evaluateJsonQuery
+    SQL_DATETIME_FORMAT, evaluateJsonQuery, PING_PACKET_SIZE_MIN, PING_PACKET_SIZE_MAX,
+    PING_DEADLINE_MIN, PING_DEADLINE_MAX, PING_COUNT_MIN, PING_COUNT_MAX, PING_TIMEOUT_MIN, PING_TIMEOUT_MAX
 } = require("../../src/util");
 const { tcping, ping, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mssqlQuery, postgresQuery, mysqlQuery, setSetting, httpNtlm, radius, grpcQuery,
     redisPingAsync, kafkaProducerAsync, getOidcTokenClientCredentials, rootCertificatesFingerprints, axiosAbortSignal
@@ -155,6 +156,12 @@ class Monitor extends BeanModel {
             snmpVersion: this.snmpVersion,
             rabbitmqNodes: JSON.parse(this.rabbitmqNodes),
             conditions: JSON.parse(this.conditions),
+
+            // ping advanced options
+            ping_numeric: this.isPingNumeric(),
+            ping_count: this.ping_count,
+            ping_deadline: this.ping_deadline,
+            ping_timeout: this.ping_timeout,
         };
 
         if (includeSensitiveData) {
@@ -247,6 +254,14 @@ class Monitor extends BeanModel {
         return Boolean(this.expiryNotification);
     }
 
+    /**
+     * Check if ping should use numeric output only
+     * @returns {boolean} True if IP addresses will be output instead of symbolic hostnames
+     */
+    isPingNumeric() {
+        return Boolean(this.ping_numeric);
+    }
+
     /**
      * Parse to boolean
      * @returns {boolean} Should TLS errors be ignored?
@@ -1500,6 +1515,22 @@ class Monitor extends BeanModel {
         if (this.interval < MIN_INTERVAL_SECOND) {
             throw new Error(`Interval cannot be less than ${MIN_INTERVAL_SECOND} seconds`);
         }
+
+        if (this.packetSize && (this.packetSize < PING_PACKET_SIZE_MIN || this.packetSize > PING_PACKET_SIZE_MAX)) {
+            throw new Error(`Packet size must be between ${PING_PACKET_SIZE_MIN} and ${PING_PACKET_SIZE_MAX}`);
+        }
+        
+        if (this.ping_deadline && (this.ping_deadline < PING_DEADLINE_MIN || this.ping_deadline > PING_DEADLINE_MAX)) {
+            throw new Error(`Deadline must be between ${PING_DEADLINE_MIN} and ${PING_DEADLINE_MAX} seconds`);
+        }
+        
+        if (this.ping_count && (this.ping_count < PING_COUNT_MIN || this.ping_count > PING_COUNT_MAX)) {
+            throw new Error(`Echo requests count must be between ${PING_COUNT_MIN} and ${PING_COUNT_MAX}`);
+        }
+        
+        if (this.ping_timeout && (this.ping_timeout < PING_TIMEOUT_MIN || this.ping_timeout > PING_TIMEOUT_MAX)) {
+            throw new Error(`Timeout must be between ${PING_TIMEOUT_MIN} and ${PING_TIMEOUT_MAX} seconds`);
+        }
     }
 
     /**
diff --git a/server/server.js b/server/server.js
index ec5ad49f6..38b93acf9 100644
--- a/server/server.js
+++ b/server/server.js
@@ -875,6 +875,12 @@ let needSetup = false;
                 bean.rabbitmqPassword = monitor.rabbitmqPassword;
                 bean.conditions = JSON.stringify(monitor.conditions);
 
+                // ping advanced options
+                bean.ping_numeric = monitor.ping_numeric;
+                bean.ping_count = monitor.ping_count;
+                bean.ping_deadline = monitor.ping_deadline;
+                bean.ping_timeout = monitor.ping_timeout;
+
                 bean.validate();
 
                 await R.store(bean);