From: Vsevolod Stakhov Date: Sat, 14 Feb 2026 19:17:22 +0000 (+0000) Subject: [Feature] Sync UUID v7 random portion with Log-Tag header X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed3e0a8b0ce6c5ef4c3f3a7e623bdedc9ee1172b;p=thirdparty%2Frspamd.git [Feature] Sync UUID v7 random portion with Log-Tag header When an MTA provides a Log-Tag header that overrides the pool UID, patch the task UUID's random portion (bytes 8-15) to stay in sync. Uses a fast hash of the tag to derive the bytes while preserving the UUID v7 variant bits. --- diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index a50f0aedae..092c4855dd 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -528,6 +528,8 @@ rspamd_protocol_set_log_tag(struct rspamd_task *task, int len = MIN(tag_len, sizeof(task->task_pool->tag.uid) - 1); memcpy(task->task_pool->tag.uid, tag, len); task->task_pool->tag.uid[len] = '\0'; + /* Keep UUID random portion in sync with the new log tag */ + rspamd_uuid_v7_patch_uid(task->task_uuid, tag, tag_len); } } diff --git a/src/libutil/util.c b/src/libutil/util.c index 9c1ea18fe9..7714195c4b 100644 --- a/src/libutil/util.c +++ b/src/libutil/util.c @@ -1667,6 +1667,25 @@ int rspamd_uuid_v7(char uuid_out[37], char *opt_uid_buf, gsize uid_buflen, doubl return 0; } +void rspamd_uuid_v7_patch_uid(char uuid[37], const char *tag, gsize tag_len) +{ + uint8_t bytes[8]; + char hex[16]; + + /* Hash the tag to get 8 bytes for UUID positions 8-15 */ + uint64_t h = rspamd_cryptobox_fast_hash(tag, tag_len, 0x7569645f763700ULL); + memcpy(bytes, &h, sizeof(h)); + + /* Preserve variant bits: byte 8 must have top 2 bits = 10 */ + bytes[0] = 0x80 | (bytes[0] & 0x3f); + + /* Hex-encode and patch into UUID string: + * positions 19-22 = bytes 8-9, positions 24-35 = bytes 10-15 */ + rspamd_encode_hex_buf(bytes, 8, hex, sizeof(hex)); + memcpy(uuid + 19, hex, 4); + memcpy(uuid + 24, hex + 4, 12); +} + int rspamd_shmem_mkstemp(char *pattern) { int fd = -1; diff --git a/src/libutil/util.h b/src/libutil/util.h index 34b7a685ab..0cff29b724 100644 --- a/src/libutil/util.h +++ b/src/libutil/util.h @@ -390,6 +390,15 @@ void rspamd_random_hex(char *buf, uint64_t len); */ int rspamd_uuid_v7(char uuid_out[37], char *opt_uid_buf, gsize uid_buflen, double timestamp); +/** + * Patch UUID v7 random portion (bytes 8-15) to match a new log tag. + * Hashes the tag to derive bytes, preserves timestamp and version/variant bits. + * @param uuid UUID string to patch in place (36 chars + NUL) + * @param tag new log tag value + * @param tag_len length of tag + */ +void rspamd_uuid_v7_patch_uid(char uuid[37], const char *tag, gsize tag_len); + /** * Returns * @param pattern pattern to create (should end with some number of X symbols), modified by this function