/** * Decode major/minor and release information from the specified two * contiguous GUID bytes. * * @param guid is the GUID considered * @param start is the offset of the markup (2 or 4) in the GUID * @param majp is filled with the major version if it's a GTKG markup * @param minp is filled with the minor version if it's a GTKG markup * @param relp is filled with the release status if it's a GTKG markup * * @return whether we recognized a GTKG markup. */ static bool guid_extract_gtkg_info(const guid_t *guid, size_t start, uint8 *majp, uint8 *minp, bool *relp) { uint8 major; uint8 minor; bool release; uint16 mark; uint16 xmark; uint8 product_major; g_assert(start < GUID_RAW_SIZE - 1); major = peek_u8(&guid->v[start]) & 0x0f; minor = peek_u8(&guid->v[start + 1]) & 0x7f; release = booleanize(0 == (peek_u8(&guid->v[start + 1]) & 0x80)); mark = guid_gtkg_encode_version(major, minor, release); xmark = peek_be16(&guid->v[start]); if (mark != xmark) return FALSE; /* * Even if by extraordinary the above check matches, make sure we're * not distant from more than one major version. Since GTKG versions * expire every year, and I don't foresee more than one major version * release per year, this strengthens the positive check. */ product_major = product_get_major(); if (major != product_major) { int8 delta = product_major - major; if (delta < -1 || delta > 1) return FALSE; } /* * We've validated the GUID: the HEC is correct and the version is * consistently encoded, judging by the highest 4 bits of guid.v[4]. */ if (majp) *majp = major; if (minp) *minp = minor; if (relp) *relp = release; return TRUE; }
/** * Initialize GUID management. */ G_GNUC_COLD void guid_init(void) { dbstore_kv_t kv = { sizeof(guid_t), NULL, sizeof(struct guiddata), 1 + sizeof(struct guiddata) /* Version byte not held in structure */ }; dbstore_packing_t packing = { serialize_guiddata, deserialize_guiddata, NULL }; char rev; /* NUL means stable release */ g_assert(NULL == db_guid); guid_gen_syndrome_table(); rev = product_get_revchar(); gtkg_version_mark = guid_gtkg_encode_version(product_get_major(), product_get_minor(), '\0' == rev); if (GNET_PROPERTY(node_debug)) g_debug("GTKG version mark is 0x%x", gtkg_version_mark); /* * Validate that guid_random_muid() correctly marks GUIDs as being GTKG's. */ { struct guid guid_buf; guid_random_muid(&guid_buf); g_assert(guid_is_gtkg(&guid_buf, NULL, NULL, NULL)); } db_guid = dbstore_open(db_guid_what, settings_gnet_db_dir(), db_guid_base, kv, packing, 1, guid_hash, guid_eq, FALSE); guid_prune_old(); guid_prune_ev = cq_periodic_main_add( GUID_PRUNE_PERIOD, guid_periodic_prune, NULL); guid_sync_ev = cq_periodic_main_add( GUID_SYNC_PERIOD, guid_periodic_sync, NULL); }