From 629cbdf5cc662b55680d96472b2fcabedff9ae2b Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 21 Jan 2022 20:51:20 +0000 Subject: [PATCH] MEDIUM: da: update module to handle schedule mode. 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 --- addons/deviceatlas/da.c | 75 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/addons/deviceatlas/da.c b/addons/deviceatlas/da.c index 418909226..969dfaa1a 100644 --- a/addons/deviceatlas/da.c +++ b/addons/deviceatlas/da.c @@ -1,4 +1,7 @@ #include +#include +#include +#include #include #include @@ -14,11 +17,16 @@ #include #include +#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,15 @@ static struct { .jsonpath = 0, .cookiename = 0, .cookienamelen = 0, + .atlasmap = NULL, + .atlasfd = -1, .useragentid = 0, .daset = 0, .separator = '|', }; +__decl_thread(HA_SPINLOCK_T dadwsch_lock); + 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 +175,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 enabled.\n"); + } + } global_deviceatlas.daset = 1; fprintf(stdout, "Deviceatlas module loaded.\n"); @@ -184,9 +206,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 +343,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 +374,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)