From 8b8ed36516e9a40df6ac9ac46ab355fee0e5b5f0 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 14 Nov 2018 14:37:31 +0100 Subject: Support generating uidNumbers on proxy --- uidmap.c | 85 ++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 42 insertions(+), 43 deletions(-) (limited to 'uidmap.c') diff --git a/uidmap.c b/uidmap.c index 8315be2..a1cb9f7 100644 --- a/uidmap.c +++ b/uidmap.c @@ -9,10 +9,6 @@ #include #include -static struct hashmap _numToName, _nameToNum; -static BOOL _initDone = FALSE; -static const char *_saveFileName = NULL; - static const uint16_t MAGIC = 1234; static const int64_t MAX_AGE = 86400 * 2; // 2 days #define MAX_NAME_LEN 1024 @@ -27,7 +23,7 @@ struct user int64_t lastUse; }; -static void insertTime(const struct string *name, const uint32_t number, const int64_t lastUse) +static void insertTime(struct uidmap *uidmap, const struct string *name, const uint32_t number, const int64_t lastUse) { uint8_t *buffer = malloc(sizeof(struct user) + sizeof(struct string) + name->l); struct user *u = (struct user*)buffer; @@ -39,18 +35,18 @@ static void insertTime(const struct string *name, const uint32_t number, const i u->name = s; u->number = number; u->lastUse = lastUse; - if (name_hashmap_put(&_nameToNum, u->name, u) != u) { + if (name_hashmap_put(uidmap->nameToNum, u->name, u) != u) { plog(DEBUG_WARNING, "[uidmap] Collision when inserting %.*s by name (%"PRIu32")", (int)s->l, s->s, number); } - if (number_hashmap_put(&_numToName, &u->number, u) != u) { + if (number_hashmap_put(uidmap->numToName, &u->number, u) != u) { plog(DEBUG_WARNING, "[uidmap] Collision when inserting %.*s by number (%"PRIu32")", (int)s->l, s->s, number); } // TODO: Leak } -static void insert(const struct string *name, const uint32_t number) +static void insert(struct uidmap *uidmap, const struct string *name, const uint32_t number) { - insertTime(name, number, time(NULL)); + insertTime(uidmap, name, number, time(NULL)); } static int uint32_compare(const void *a, const void *b) @@ -84,7 +80,7 @@ static size_t string_hash(const void *key) return hash; } -uint32_t uidmap_getNumberForName(const struct string *name) +uint32_t uidmap_getNumberForName(struct uidmap *uidmap, const struct string *name) { // Try string matching char buf[name->l]; @@ -93,7 +89,7 @@ uint32_t uidmap_getNumberForName(const struct string *name) buf[i] = tolower(name->s[i]); } // Get - struct user *u = name_hashmap_get(&_nameToNum, &lower); + struct user *u = name_hashmap_get(uidmap->nameToNum, &lower); if (u != NULL) { u->lastUse = time(NULL); return u->number; @@ -101,10 +97,10 @@ uint32_t uidmap_getNumberForName(const struct string *name) // Not known yet - try numeric uint32_t asNumber = parseUInt32(name); if (asNumber >= 2000) { - u = number_hashmap_get(&_numToName, &asNumber); + u = number_hashmap_get(uidmap->numToName, &asNumber); if (u == NULL) { // No collision, use name as number - insert(&lower, asNumber); + insert(uidmap, &lower, asNumber); return asNumber; } plog(DEBUG_WARNING, "%.*s is numeric (%u) but collides", (int)name->l, name->s, asNumber); @@ -116,49 +112,52 @@ uint32_t uidmap_getNumberForName(const struct string *name) } for (;;) { //plog(DEBUG_WARNING, "Using number %u for %.*s", asNumber, (int)name->l, name->s); - u = number_hashmap_get(&_numToName, &asNumber); + u = number_hashmap_get(uidmap->numToName, &asNumber); if (u == NULL) break; do { asNumber = rand() + 2000; } while (asNumber < 2000); } - insert(&lower, asNumber); + insert(uidmap, &lower, asNumber); return asNumber; } -const struct string *uidmap_getNameForNumber(const uint32_t number) +const struct string *uidmap_getNameForNumber(struct uidmap *uidmap, const struct string *numberString) { - struct user *u = number_hashmap_get(&_numToName, &number); + uint32_t number = parseUInt32(numberString); + if (number < 2000) + return NULL; + struct user *u = number_hashmap_get(uidmap->numToName, &number); if (u == NULL) return NULL; u->lastUse = time(NULL); return u->name; } -void uidmap_init(const char *fileName) +void uidmap_init(struct uidmap *uidmap) { - if (_initDone) + if (uidmap->nameToNum != NULL) return; - _initDone = TRUE; - hashmap_init(&_numToName, uint32_hash, uint32_compare, 0); - hashmap_init(&_nameToNum, string_hash, string_compare, 0); - if (fileName == NULL) + uidmap->numToName = calloc(2, sizeof(struct hashmap)); + uidmap->nameToNum = uidmap->numToName + 1; + hashmap_init(uidmap->numToName, uint32_hash, uint32_compare, 0); + hashmap_init(uidmap->nameToNum, string_hash, string_compare, 0); + if (uidmap->fileName == NULL) return; - // We have a filename, remember it and try to load DB - _saveFileName = strdup(fileName); - FILE *fh = fopen(_saveFileName, "rb"); + // We have a filename, try to load DB + FILE *fh = fopen(uidmap->fileName, "rb"); if (fh == NULL) return; fseek(fh, 0, SEEK_END); const int fsize = ftell(fh); fseek(fh, 0, SEEK_SET); - if (fsize > 0) { + if (fsize > 0) { // Guess required map size const size_t entries = (size_t)fsize / 25; - hashmap_destroy(&_numToName); - hashmap_destroy(&_nameToNum); - hashmap_init(&_numToName, uint32_hash, uint32_compare, entries); - hashmap_init(&_nameToNum, string_hash, string_compare, entries); + hashmap_destroy(uidmap->numToName); + hashmap_destroy(uidmap->nameToNum); + hashmap_init(uidmap->numToName, uint32_hash, uint32_compare, entries); + hashmap_init(uidmap->nameToNum, string_hash, string_compare, entries); } // Not endian safe, do not copy file around... uint16_t len = 0; @@ -196,38 +195,38 @@ void uidmap_init(const char *fileName) lastUse = now; // Add name.l = len; - insertTime(&name, uidNumber, lastUse); + insertTime(uidmap, &name, uidNumber, lastUse); loaded++; } fclose(fh); - plog(DEBUG_INFO, "Loaded %d entries from %s", loaded, _saveFileName); + plog(DEBUG_INFO, "Loaded %d entries from %s", loaded, uidmap->fileName); } -void uidmap_cleanupSave() +void uidmap_cleanupSave(struct uidmap *uidmap) { - if (!_initDone) + if (uidmap->nameToNum == NULL) return; FILE *fh = NULL; - if (_saveFileName != NULL) { - fh = fopen(_saveFileName, "wb"); + if (uidmap->fileName != NULL) { + fh = fopen(uidmap->fileName, "wb"); if (fh != NULL) { if (fwrite(&MAGIC, sizeof(MAGIC), 1, fh) != 1) { - plog(DEBUG_WARNING, "Cannot write magic to %s", _saveFileName); + plog(DEBUG_WARNING, "Cannot write magic to %s", uidmap->fileName); fclose(fh); fh = NULL; } } } const int64_t deadline = time(NULL) - MAX_AGE; - struct hashmap_iter *it = hashmap_iter(&_nameToNum); + struct hashmap_iter *it = hashmap_iter(uidmap->nameToNum); struct user *u = NULL; int saved = 0, removed = 0; uint16_t len; while (it != NULL) { u = name_hashmap_iter_get_data(it); if (u->lastUse < deadline) { - it = hashmap_iter_remove(&_nameToNum, it); - if (number_hashmap_remove(&_numToName, &u->number) != u) { + it = hashmap_iter_remove(uidmap->nameToNum, it); + if (number_hashmap_remove(uidmap->numToName, &u->number) != u) { plog(DEBUG_WARNING, "Could not remove user from numToName that was in nameToNum"); } free(u); @@ -242,14 +241,14 @@ void uidmap_cleanupSave() || fwrite(&u->number, sizeof(u->number), 1, fh) != 1 || fwrite(u->name->s, len, 1, fh) != 1 ) { - plog(DEBUG_WARNING, "Could not write record to %s", _saveFileName); + plog(DEBUG_WARNING, "Could not write record to %s", uidmap->fileName); fclose(fh); fh = NULL; } else { saved++; } } - it = hashmap_iter_next(&_nameToNum, it); + it = hashmap_iter_next(uidmap->nameToNum, it); } if (fh != NULL) { fsync(fileno(fh)); -- cgit v1.2.3-55-g7522