Skip to content

Commit

Permalink
Add events to track clients and servers
Browse files Browse the repository at this point in the history
  • Loading branch information
pascal-fb-martin committed Dec 26, 2021
1 parent dfae1a2 commit fd3881a
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 0 deletions.
89 changes: 89 additions & 0 deletions hc_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,12 @@
#include "echttp_cors.h"
#include "echttp_static.h"
#include "houseportalclient.h"
#include "houselog.h"

static pid_t parent;

static long hc_known_clients[256]; // Enough to store IP v4 address.
static long hc_known_servers[256]; // Enough to store IP v4 address.

static hc_clock_status *clock_db = 0;
static hc_nmea_status *nmea_db = 0;
Expand All @@ -63,6 +66,7 @@ static char JsonBuffer[16384];
static void hc_background (int fd, int mode) {
static time_t LastParentCheck = 0;
static time_t LastRenewal = 0;
static time_t LastActivityCheck = 0;

time_t now = time(0);

Expand Down Expand Up @@ -90,6 +94,89 @@ static void hc_background (int fd, int mode) {
LastRenewal = now;
}
}

if (ntp_db && (now >= LastActivityCheck + 5)) {


// Generate events for new or unsynchronized clients.
// We generate a local "cache" of known clients to limit the number of
// events generated when the clent is not synchronized. The cache key
// is the low 7 bits of the IP address, plus the ninth bit: this works
// best for me because I have two subnets, while I don't have anywhere
// close to 127 machines at home.
// This should work fine for most home networks.
//
int i;
for (i = 0; i < HC_NTP_DEPTH; ++i) {
struct hc_ntp_client *client = ntp_db->clients + i;

// Do not consider events that are empty or too old (risk of
// race condition)
//
if ((client->local.tv_sec < LastActivityCheck)
|| (client->local.tv_sec == 0)) continue;

// Do not consider events that were already detected.
//
if (client->logged) continue;

if (abs(client->origin.tv_sec - client->local.tv_sec) > 600) {
houselog_event ("CLIENT", hc_broadcast_format (&(client->address)),
"ACTIVE", "NOT SYNCHRONIZED");
} else {
long adr = ntohl(client->address.sin_addr.s_addr);
int hash = (int) ((adr & 0x7f) | ((adr & 0x100) >> 1));

int delta =
((client->origin.tv_sec - client->local.tv_sec) * 1000)
+ ((client->origin.tv_usec - client->local.tv_usec) / 1000);

if ((hc_known_clients[hash] == adr) && (abs(delta) < 10000)) continue;
houselog_event ("CLIENT", hc_broadcast_format (&(client->address)),
"ACTIVE", "DELTA %d MS", delta);

hc_known_clients[hash] = adr;
}
client->logged = 1;
}

// Generate events for newly detected servers, using a similar cache
// as for clients to limit the rate of events when synchronized.
//
for (i = 0; i < HC_NTP_POOL; ++i) {
struct hc_ntp_server *server = ntp_db->pool + i;

// Do not consider events that are empty or too old (risk of
// race condition)
//
if ((server->local.tv_sec < LastActivityCheck)
|| (server->local.tv_sec == 0)) continue;

// Do not consider events that were already detected.
//
if (server->logged) continue;

if (abs(server->origin.tv_sec - server->local.tv_sec) > 600) {
houselog_event ("SERVER", server->name, "ACTIVE",
"STRATUM %d, NOT SYNCHRONIZED", server->stratum);
} else {
long adr = ntohl(server->address.sin_addr.s_addr);
int hash = (int) ((adr & 0x7f) | ((adr & 0x100) >> 1));

int delta =
((server->origin.tv_sec - server->local.tv_sec) * 1000)
+ ((server->origin.tv_usec - server->local.tv_usec) / 1000);

if ((hc_known_servers[hash] == adr) && (abs(delta) < 10000)) continue;
houselog_event ("SERVER", server->name, "ACTIVE",
"STRATUM %d, DELTA %d MS", server->stratum, delta);

hc_known_servers[hash] = adr;
}
server->logged = 1;
}
LastActivityCheck = now;
}
}

static void *hc_http_attach (const char *name) {
Expand Down Expand Up @@ -474,6 +561,7 @@ void hc_http (int argc, const char **argv) {
houseportal_initialize (argc, argv);
use_houseportal = 1;
}
houselog_initialize ("ntp", argc, argv);

echttp_cors_allow_method("GET");
echttp_protect (0, hc_protect);
Expand All @@ -485,6 +573,7 @@ void hc_http (int argc, const char **argv) {
echttp_route_uri ("/ntp/server", hc_http_ntp);
echttp_static_route ("/", "/usr/local/share/house/public");
echttp_background (&hc_background);
houselog_event ("SERVICE", "ntp", "STARTED", "ON %s", houselog_host());
echttp_loop();
exit (0);
}
Expand Down
2 changes: 2 additions & 0 deletions hc_ntp.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ static void hc_ntp_broadcastmsg (const ntpHeaderV3 *head,
hc_ntp_status_db->pool[sender].stratum = head->stratum;
hc_ntp_get_timestamp
(&(hc_ntp_status_db->pool[sender].origin), &(head->transmit));
hc_ntp_status_db->pool[sender].logged = 0;

// Elect a time source. Choose the lowest stratum available.
//
Expand Down Expand Up @@ -413,6 +414,7 @@ static void hc_ntp_requestmsg (const ntpHeaderV3 *head,
(&(hc_ntp_status_db->clients[hc_ntp_client_cursor].origin),
&(ntpResponse.origin));
hc_ntp_status_db->clients[hc_ntp_client_cursor].local = *receive;
hc_ntp_status_db->clients[hc_ntp_client_cursor].logged = 0;
}


Expand Down
2 changes: 2 additions & 0 deletions hc_ntp.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct hc_ntp_client {
struct sockaddr_in address;
struct timeval origin;
struct timeval local;
int logged;
};

struct hc_ntp_server {
Expand All @@ -52,6 +53,7 @@ struct hc_ntp_server {
short stratum;
struct sockaddr_in address;
char name[48];
int logged;
};

typedef struct {
Expand Down
118 changes: 118 additions & 0 deletions public/events.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<!DOCTYPE html>
<html>
<head>
<link rel=stylesheet type="text/css" href="/house.css" title="House">
<script>
function ntpShowStatus (response) {
document.getElementById('portal').href = 'http://'+response.proxy+'/index.html';
}

function ntpStatus () {
var command = new XMLHttpRequest();
command.open("GET", "/ntp/status");
command.onreadystatechange = function () {
if (command.readyState === 4 && command.status === 200) {
ntpShowStatus (JSON.parse(command.responseText));
}
}
command.send(null);
}
window.onload = function() {

function newColumn (text) {
var column = document.createElement("td");
column.innerHTML = text;
return column;
}

var lastEventId = null;

function showEvents (response) {

if (!lastEventId) {
var title = response.host + ' - Kasa Devices';
document.getElementsByTagName ('title')[0].innerHTML = title;
var elements = document.getElementsByClassName ('hostname');
for (var i = 0; i < elements.length; i++) {
elements[i].innerHTML = response.host;
}
}

lastEventId = response.ntp.latest;

var table = document.getElementsByClassName ('eventlist')[0];
for (var i = table.childNodes.length - 1; i > 1; i--) {
table.removeChild(table.childNodes[i]);
}
for (var i = response.ntp.events.length-1; i >= 0; --i) {
var event = response.ntp.events[i];
var timestamp = new Date(event[0]);
var row = document.createElement("tr");
row.appendChild(newColumn(timestamp.toLocaleString()));
row.appendChild(newColumn(event[1]));
row.appendChild(newColumn(event[2]));
row.appendChild(newColumn(event[3]));
row.appendChild(newColumn(event[4]));
table.appendChild(row);
}
}

function updateEvents() {

var command = new XMLHttpRequest();
command.open("GET", "/ntp/log/events");
command.onreadystatechange = function () {
if (command.readyState === 4 && command.status === 200) {
showEvents (JSON.parse(command.responseText));
}
}
command.send(null);
}

function checkEvents () {

var command = new XMLHttpRequest();
command.open("GET", "/ntp/log/latest");
command.onreadystatechange = function () {
if (command.readyState === 4 && command.status === 200) {
var response = JSON.parse(command.responseText);
if ((lastEventId == null) ||
(response.ntp.latest != lastEventId)) updateEvents ();
}
}
command.send(null);
}

updateEvents();
setInterval (function() {checkEvents()}, 1000);
ntpStatus();
}
</script>
<head>
<title></title>
</head>
<body>
<table class="housetopcontainer">
<tr><td>
<table class="housetop">
<tr>
<td><a id="portal" href="/index.html">Portal</a></td>
<td><a href="/ntp/index.html">Clock</a></td>
<td><span>Events</span></td>
</tr>
</table>
</td></tr>
</table>
<h1><span class="hostname"></span></h1>
<table class="housewidetable eventlist" border="0">
<tr>
<th width="15%">Time</th>
<th width="10%">Category</th>
<th width="15%">Name</th>
<th width="15%">Action</th>
<th width="45%">Description</th>
</tr>
</table>
</body>
</html>

1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<tr>
<td><a id="portal" href="/index.html">Portal</a></td>
<td><span>Clock</span></td>
<td><a href="/ntp/events.html">Events</a></td>
</tr>
</table>
</td></tr>
Expand Down

0 comments on commit fd3881a

Please sign in to comment.