Second patch of the patchset concerning the update of the addon itself.
From d541d8dfd8aa0290625b3824bd6b44d2861e997f Mon Sep 17 00:00:00 2001
From: David Carlier <[email protected]>
Date: Fri, 21 Jan 2022 20:51:20 +0000
Subject: [PATCH 2/3] MEDIUM: deviceatlas update of the main module.

The DeviceAtlas addon can optionally interacts with the new service
 without change of configuration in the HAProxy part.
Note that however it requires the DeviceAtlas Identification C API
2.4.0 minimum from this point.

Signed-off-by: David Carlier <[email protected]>
---
 addons/deviceatlas/da.c | 77 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/addons/deviceatlas/da.c b/addons/deviceatlas/da.c
index 418909226..724209936 100644
--- a/addons/deviceatlas/da.c
+++ b/addons/deviceatlas/da.c
@@ -1,4 +1,7 @@
 #include <stdio.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <errno.h>
 
 #include <haproxy/api.h>
 #include <haproxy/arg.h>
@@ -14,11 +17,16 @@
 #include <haproxy/tools.h>
 #include <dac.h>
 
+#define ATLASTOKSZ PATH_MAX
+#define ATLASMAPNM "/hapdeviceatlas"
+
 static struct {
 	void *atlasimgptr;
+	void *atlasmap;
 	char *jsonpath;
 	char *cookiename;
 	size_t cookienamelen;
+	int atlasfd;
 	da_atlas_t atlas;
 	da_evidence_id_t useragentid;
 	da_severity_t loglevel;
@@ -29,11 +37,17 @@ static struct {
 	.jsonpath = 0,
 	.cookiename = 0,
 	.cookienamelen = 0,
+	.atlasmap = NULL,
+	.atlasfd = -1,
 	.useragentid = 0,
 	.daset = 0,
 	.separator = '|',
 };
 
+#ifdef USE_THREAD
+__decl_spinlock(dadwsch_lock);
+#endif
+
 static int da_json_file(char **args, int section_type, struct proxy *curpx,
                         const struct proxy *defpx, const char *file, int line,
                         char **err)
@@ -163,6 +177,16 @@ static int init_deviceatlas(void)
 
 		global_deviceatlas.useragentid = da_atlas_header_evidence_id(&global_deviceatlas.atlas,
 			"user-agent");
+		if ((global_deviceatlas.atlasfd = shm_open(ATLASMAPNM, O_RDWR, 0660)) != -1) {
+			global_deviceatlas.atlasmap = mmap(NULL, ATLASTOKSZ, PROT_READ | PROT_WRITE, MAP_SHARED, global_deviceatlas.atlasfd, 0);
+			if (global_deviceatlas.atlasmap == MAP_FAILED) {
+				close(global_deviceatlas.atlasfd);
+				global_deviceatlas.atlasfd = -1;
+				global_deviceatlas.atlasmap = NULL;
+			} else {
+				fprintf(stdout, "deviceatlas : scheduling support.\n");
+			}
+		}
 		global_deviceatlas.daset = 1;
 
 		fprintf(stdout, "Deviceatlas module loaded.\n");
@@ -184,9 +208,58 @@ static void deinit_deviceatlas(void)
 		free(global_deviceatlas.atlasimgptr);
 	}
 
+	if (global_deviceatlas.atlasfd != -1) {
+		munmap(global_deviceatlas.atlasmap, ATLASTOKSZ);
+		close(global_deviceatlas.atlasfd);
+		shm_unlink(ATLASMAPNM);
+	}
+
 	da_fini();
 }
 
+static void da_haproxy_checkinst(void)
+{
+	if (global_deviceatlas.atlasmap != 0) {
+		char *base;
+		base = (char *)global_deviceatlas.atlasmap;
+
+		if (base[0] != 0) {
+			void *cnew;
+			size_t atlassz;
+			char atlasp[ATLASTOKSZ] = {0};
+			da_atlas_t inst;
+			da_property_decl_t extraprops[1] = {{NULL, 0}};
+#ifdef USE_THREAD
+			HA_SPIN_LOCK(OTHER_LOCK, &dadwsch_lock);
+#endif
+			strlcpy2(atlasp, base, sizeof(atlasp));
+			if (da_atlas_read_mapped(atlasp, NULL, &cnew, &atlassz) == DA_OK) {
+				if (da_atlas_open(&inst, extraprops, cnew, atlassz) == DA_OK) {
+					char jsonbuf[26];
+					time_t jsond;
+
+					da_atlas_close(&global_deviceatlas.atlas);
+					free(global_deviceatlas.atlasimgptr);
+					global_deviceatlas.atlasimgptr = cnew;
+					global_deviceatlas.atlas = inst;
+					memset(base, 0, ATLASTOKSZ);
+					jsond = da_getdatacreation(&global_deviceatlas.atlas);
+					ctime_r(&jsond, jsonbuf);
+					jsonbuf[24] = 0;
+					printf("deviceatlas: new instance, data file date `%s`.\n", jsonbuf);
+				} else {
+					ha_warning("deviceatlas: instance update failed.\n");
+					memset(base, 0, ATLASTOKSZ);
+					free(cnew);
+				}
+			}
+#ifdef USE_THREAD
+			HA_SPIN_UNLOCK(OTHER_LOCK, &dadwsch_lock);
+#endif
+		}
+	}
+}
+
 static int da_haproxy(const struct arg *args, struct sample *smp, da_deviceinfo_t *devinfo)
 {
 	struct buffer *tmp;
@@ -272,6 +345,8 @@ static int da_haproxy_conv(const struct arg *args, struct sample *smp, void *pri
 		return 1;
 	}
 
+	da_haproxy_checkinst();
+
 	i = smp->data.u.str.data > sizeof(useragentbuf) ? sizeof(useragentbuf) : smp->data.u.str.data;
 	memcpy(useragentbuf, smp->data.u.str.area, i - 1);
 	useragentbuf[i - 1] = 0;
@@ -301,6 +376,8 @@ static int da_haproxy_fetch(const struct arg *args, struct sample *smp, const ch
 		return 0;
 	}
 
+	da_haproxy_checkinst();
+
 	chn = (smp->strm ? &smp->strm->req : NULL);
 	htx = smp_prefetch_htx(smp, chn, NULL, 1);
 	if (!htx)
-- 
2.30.2

Reply via email to