From b904896a954206e3862c9b9a67f4379113198361 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 16 May 2020 10:24:52 +0000 Subject: [PATCH] Bump database version to "1" Signed-off-by: Michael Tremer --- src/as.c | 8 +-- src/country.c | 8 +-- src/database.c | 110 ++++++++++++++++---------------- src/loc/as.h | 8 +-- src/loc/country.h | 8 +-- src/loc/format.h | 19 ++++-- src/loc/network.h | 6 +- src/loc/writer.h | 4 +- src/network.c | 6 +- src/python/location-importer.in | 1 + src/python/writer.c | 6 +- src/resolv.c | 2 +- src/test-as.c | 2 +- src/test-country.c | 2 +- src/test-database.c | 2 +- src/test-network.c | 2 +- src/test-signature.c | 2 +- src/writer.c | 48 +++++++++----- 18 files changed, 136 insertions(+), 108 deletions(-) diff --git a/src/as.c b/src/as.c index f5e7dd4..e1fbb01 100644 --- a/src/as.c +++ b/src/as.c @@ -105,8 +105,8 @@ LOC_EXPORT int loc_as_cmp(struct loc_as* as1, struct loc_as* as2) { return 0; } -int loc_as_new_from_database_v0(struct loc_ctx* ctx, struct loc_stringpool* pool, - struct loc_as** as, const struct loc_database_as_v0* dbobj) { +int loc_as_new_from_database_v1(struct loc_ctx* ctx, struct loc_stringpool* pool, + struct loc_as** as, const struct loc_database_as_v1* dbobj) { uint32_t number = be32toh(dbobj->number); int r = loc_as_new(ctx, as, number); @@ -123,8 +123,8 @@ int loc_as_new_from_database_v0(struct loc_ctx* ctx, struct loc_stringpool* pool return 0; } -int loc_as_to_database_v0(struct loc_as* as, struct loc_stringpool* pool, - struct loc_database_as_v0* dbobj) { +int loc_as_to_database_v1(struct loc_as* as, struct loc_stringpool* pool, + struct loc_database_as_v1* dbobj) { dbobj->number = htobe32(as->number); // Save the name string in the string pool diff --git a/src/country.c b/src/country.c index 45d26b8..d6ddf50 100644 --- a/src/country.c +++ b/src/country.c @@ -118,8 +118,8 @@ LOC_EXPORT int loc_country_cmp(struct loc_country* country1, struct loc_country* return strcmp(country1->code, country2->code); } -int loc_country_new_from_database_v0(struct loc_ctx* ctx, struct loc_stringpool* pool, - struct loc_country** country, const struct loc_database_country_v0* dbobj) { +int loc_country_new_from_database_v1(struct loc_ctx* ctx, struct loc_stringpool* pool, + struct loc_country** country, const struct loc_database_country_v1* dbobj) { char buffer[3]; // Read country code @@ -152,8 +152,8 @@ FAIL: return r; } -int loc_country_to_database_v0(struct loc_country* country, - struct loc_stringpool* pool, struct loc_database_country_v0* dbobj) { +int loc_country_to_database_v1(struct loc_country* country, + struct loc_stringpool* pool, struct loc_database_country_v1* dbobj) { // Add country code for (unsigned int i = 0; i < 2; i++) { dbobj->code[i] = country->code[i] ? country->code[i] : '\0'; diff --git a/src/database.c b/src/database.c index fc97a2f..443ed1e 100644 --- a/src/database.c +++ b/src/database.c @@ -62,19 +62,19 @@ struct loc_database { size_t signature_length; // ASes in the database - struct loc_database_as_v0* as_v0; + struct loc_database_as_v1* as_v1; size_t as_count; // Network tree - struct loc_database_network_node_v0* network_nodes_v0; + struct loc_database_network_node_v1* network_nodes_v1; size_t network_nodes_count; // Networks - struct loc_database_network_v0* networks_v0; + struct loc_database_network_v1* networks_v1; size_t networks_count; // Countries - struct loc_database_country_v0* countries_v0; + struct loc_database_country_v1* countries_v1; size_t countries_count; struct loc_stringpool* pool; @@ -141,30 +141,30 @@ static int loc_database_read_magic(struct loc_database* db) { return 1; } -static int loc_database_read_as_section_v0(struct loc_database* db, - const struct loc_database_header_v0* header) { +static int loc_database_read_as_section_v1(struct loc_database* db, + const struct loc_database_header_v1* header) { off_t as_offset = be32toh(header->as_offset); size_t as_length = be32toh(header->as_length); DEBUG(db->ctx, "Reading AS section from %jd (%zu bytes)\n", (intmax_t)as_offset, as_length); if (as_length > 0) { - db->as_v0 = mmap(NULL, as_length, PROT_READ, + db->as_v1 = mmap(NULL, as_length, PROT_READ, MAP_SHARED, fileno(db->f), as_offset); - if (db->as_v0 == MAP_FAILED) + if (db->as_v1 == MAP_FAILED) return -errno; } - db->as_count = as_length / sizeof(*db->as_v0); + db->as_count = as_length / sizeof(*db->as_v1); INFO(db->ctx, "Read %zu ASes from the database\n", db->as_count); return 0; } -static int loc_database_read_network_nodes_section_v0(struct loc_database* db, - const struct loc_database_header_v0* header) { +static int loc_database_read_network_nodes_section_v1(struct loc_database* db, + const struct loc_database_header_v1* header) { off_t network_nodes_offset = be32toh(header->network_tree_offset); size_t network_nodes_length = be32toh(header->network_tree_length); @@ -172,22 +172,22 @@ static int loc_database_read_network_nodes_section_v0(struct loc_database* db, (intmax_t)network_nodes_offset, network_nodes_length); if (network_nodes_length > 0) { - db->network_nodes_v0 = mmap(NULL, network_nodes_length, PROT_READ, + db->network_nodes_v1 = mmap(NULL, network_nodes_length, PROT_READ, MAP_SHARED, fileno(db->f), network_nodes_offset); - if (db->network_nodes_v0 == MAP_FAILED) + if (db->network_nodes_v1 == MAP_FAILED) return -errno; } - db->network_nodes_count = network_nodes_length / sizeof(*db->network_nodes_v0); + db->network_nodes_count = network_nodes_length / sizeof(*db->network_nodes_v1); INFO(db->ctx, "Read %zu network nodes from the database\n", db->network_nodes_count); return 0; } -static int loc_database_read_networks_section_v0(struct loc_database* db, - const struct loc_database_header_v0* header) { +static int loc_database_read_networks_section_v1(struct loc_database* db, + const struct loc_database_header_v1* header) { off_t networks_offset = be32toh(header->network_data_offset); size_t networks_length = be32toh(header->network_data_length); @@ -195,22 +195,22 @@ static int loc_database_read_networks_section_v0(struct loc_database* db, (intmax_t)networks_offset, networks_length); if (networks_length > 0) { - db->networks_v0 = mmap(NULL, networks_length, PROT_READ, + db->networks_v1 = mmap(NULL, networks_length, PROT_READ, MAP_SHARED, fileno(db->f), networks_offset); - if (db->networks_v0 == MAP_FAILED) + if (db->networks_v1 == MAP_FAILED) return -errno; } - db->networks_count = networks_length / sizeof(*db->networks_v0); + db->networks_count = networks_length / sizeof(*db->networks_v1); INFO(db->ctx, "Read %zu networks from the database\n", db->networks_count); return 0; } -static int loc_database_read_countries_section_v0(struct loc_database* db, - const struct loc_database_header_v0* header) { +static int loc_database_read_countries_section_v1(struct loc_database* db, + const struct loc_database_header_v1* header) { off_t countries_offset = be32toh(header->countries_offset); size_t countries_length = be32toh(header->countries_length); @@ -218,14 +218,14 @@ static int loc_database_read_countries_section_v0(struct loc_database* db, (intmax_t)countries_offset, countries_length); if (countries_length > 0) { - db->countries_v0 = mmap(NULL, countries_length, PROT_READ, + db->countries_v1 = mmap(NULL, countries_length, PROT_READ, MAP_SHARED, fileno(db->f), countries_offset); - if (db->countries_v0 == MAP_FAILED) + if (db->countries_v1 == MAP_FAILED) return -errno; } - db->countries_count = countries_length / sizeof(*db->countries_v0); + db->countries_count = countries_length / sizeof(*db->countries_v1); INFO(db->ctx, "Read %zu countries from the database\n", db->countries_count); @@ -233,8 +233,8 @@ static int loc_database_read_countries_section_v0(struct loc_database* db, return 0; } -static int loc_database_read_header_v0(struct loc_database* db) { - struct loc_database_header_v0 header; +static int loc_database_read_header_v1(struct loc_database* db) { + struct loc_database_header_v1 header; // Read from file size_t size = fread(&header, 1, sizeof(header), db->f); @@ -277,22 +277,22 @@ static int loc_database_read_header_v0(struct loc_database* db) { return r; // AS section - r = loc_database_read_as_section_v0(db, &header); + r = loc_database_read_as_section_v1(db, &header); if (r) return r; // Network Nodes - r = loc_database_read_network_nodes_section_v0(db, &header); + r = loc_database_read_network_nodes_section_v1(db, &header); if (r) return r; // Networks - r = loc_database_read_networks_section_v0(db, &header); + r = loc_database_read_networks_section_v1(db, &header); if (r) return r; // countries - r = loc_database_read_countries_section_v0(db, &header); + r = loc_database_read_countries_section_v1(db, &header); if (r) return r; @@ -302,7 +302,7 @@ static int loc_database_read_header_v0(struct loc_database* db) { static int loc_database_read_header(struct loc_database* db) { switch (db->version) { case 0: - return loc_database_read_header_v0(db); + return loc_database_read_header_v1(db); default: ERROR(db->ctx, "Incompatible database version: %u\n", db->version); @@ -388,22 +388,22 @@ static void loc_database_free(struct loc_database* db) { DEBUG(db->ctx, "Releasing database %p\n", db); // Removing all ASes - if (db->as_v0) { - r = munmap(db->as_v0, db->as_count * sizeof(*db->as_v0)); + if (db->as_v1) { + r = munmap(db->as_v1, db->as_count * sizeof(*db->as_v1)); if (r) ERROR(db->ctx, "Could not unmap AS section: %s\n", strerror(errno)); } // Remove mapped network sections - if (db->networks_v0) { - r = munmap(db->networks_v0, db->networks_count * sizeof(*db->networks_v0)); + if (db->networks_v1) { + r = munmap(db->networks_v1, db->networks_count * sizeof(*db->networks_v1)); if (r) ERROR(db->ctx, "Could not unmap networks section: %s\n", strerror(errno)); } // Remove mapped network nodes section - if (db->network_nodes_v0) { - r = munmap(db->network_nodes_v0, db->network_nodes_count * sizeof(*db->network_nodes_v0)); + if (db->network_nodes_v1) { + r = munmap(db->network_nodes_v1, db->network_nodes_count * sizeof(*db->network_nodes_v1)); if (r) ERROR(db->ctx, "Could not unmap network nodes section: %s\n", strerror(errno)); } @@ -482,21 +482,21 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) { } // Read the header - struct loc_database_header_v0 header_v0; + struct loc_database_header_v1 header_v1; switch (db->version) { case 0: - fread(&header_v0, 1, sizeof(header_v0), db->f); + fread(&header_v1, 1, sizeof(header_v1), db->f); // Clear signature - for (unsigned int i = 0; i < sizeof(header_v0.signature); i++) { - header_v0.signature[i] = '\0'; + for (unsigned int i = 0; i < sizeof(header_v1.signature); i++) { + header_v1.signature[i] = '\0'; } - hexdump(db->ctx, &header_v0, sizeof(header_v0)); + hexdump(db->ctx, &header_v1, sizeof(header_v1)); // Feed header into the hash - r = EVP_DigestVerifyUpdate(mdctx, &header_v0, sizeof(header_v0)); + r = EVP_DigestVerifyUpdate(mdctx, &header_v1, sizeof(header_v1)); if (r != 1) { ERROR(db->ctx, "%s\n", ERR_error_string(ERR_get_error(), NULL)); r = 1; @@ -590,7 +590,7 @@ static int loc_database_fetch_as(struct loc_database* db, struct loc_as** as, of int r; switch (db->version) { case 0: - r = loc_as_new_from_database_v0(db->ctx, db->pool, as, db->as_v0 + pos); + r = loc_as_new_from_database_v1(db->ctx, db->pool, as, db->as_v1 + pos); break; default: @@ -663,8 +663,8 @@ static int loc_database_fetch_network(struct loc_database* db, struct loc_networ int r; switch (db->version) { case 0: - r = loc_network_new_from_database_v0(db->ctx, network, - address, prefix, db->networks_v0 + pos); + r = loc_network_new_from_database_v1(db->ctx, network, + address, prefix, db->networks_v1 + pos); break; default: @@ -680,16 +680,16 @@ static int loc_database_fetch_network(struct loc_database* db, struct loc_networ return r; } -static int __loc_database_node_is_leaf(const struct loc_database_network_node_v0* node) { +static int __loc_database_node_is_leaf(const struct loc_database_network_node_v1* node) { return (node->network != htobe32(0xffffffff)); } static int __loc_database_lookup_handle_leaf(struct loc_database* db, const struct in6_addr* address, struct loc_network** network, struct in6_addr* network_address, unsigned int prefix, - const struct loc_database_network_node_v0* node) { + const struct loc_database_network_node_v1* node) { off_t network_index = be32toh(node->network); - DEBUG(db->ctx, "Handling leaf node at %jd (%jd)\n", (intmax_t)(node - db->network_nodes_v0), (intmax_t)network_index); + DEBUG(db->ctx, "Handling leaf node at %jd (%jd)\n", (intmax_t)(node - db->network_nodes_v1), (intmax_t)network_index); // Fetch the network int r = loc_database_fetch_network(db, network, @@ -716,7 +716,7 @@ static int __loc_database_lookup_handle_leaf(struct loc_database* db, const stru // Searches for an exact match along the path static int __loc_database_lookup(struct loc_database* db, const struct in6_addr* address, struct loc_network** network, struct in6_addr* network_address, - const struct loc_database_network_node_v0* node, unsigned int level) { + const struct loc_database_network_node_v1* node, unsigned int level) { int r; off_t node_index; @@ -738,7 +738,7 @@ static int __loc_database_lookup(struct loc_database* db, const struct in6_addr* // Move on to the next node r = __loc_database_lookup(db, address, network, network_address, - db->network_nodes_v0 + node_index, level + 1); + db->network_nodes_v1 + node_index, level + 1); // End here if a result was found if (r == 0) @@ -774,7 +774,7 @@ LOC_EXPORT int loc_database_lookup(struct loc_database* db, clock_t start = clock(); int r = __loc_database_lookup(db, address, network, &network_address, - db->network_nodes_v0, 0); + db->network_nodes_v1, 0); clock_t end = clock(); @@ -807,7 +807,7 @@ static int loc_database_fetch_country(struct loc_database* db, int r; switch (db->version) { case 0: - r = loc_country_new_from_database_v0(db->ctx, db->pool, country, db->countries_v0 + pos); + r = loc_country_new_from_database_v1(db->ctx, db->pool, country, db->countries_v1 + pos); break; default: @@ -1083,8 +1083,8 @@ LOC_EXPORT int loc_database_enumerator_next_network( enumerator->networks_visited[node->offset]++; // Pop node from top of the stack - struct loc_database_network_node_v0* n = - enumerator->db->network_nodes_v0 + node->offset; + struct loc_database_network_node_v1* n = + enumerator->db->network_nodes_v1 + node->offset; // Add edges to stack r = loc_database_enumerator_stack_push_node(enumerator, diff --git a/src/loc/as.h b/src/loc/as.h index df00119..b4c8e1d 100644 --- a/src/loc/as.h +++ b/src/loc/as.h @@ -37,10 +37,10 @@ int loc_as_cmp(struct loc_as* as1, struct loc_as* as2); #ifdef LIBLOC_PRIVATE -int loc_as_new_from_database_v0(struct loc_ctx* ctx, struct loc_stringpool* pool, - struct loc_as** as, const struct loc_database_as_v0* dbobj); -int loc_as_to_database_v0(struct loc_as* as, struct loc_stringpool* pool, - struct loc_database_as_v0* dbobj); +int loc_as_new_from_database_v1(struct loc_ctx* ctx, struct loc_stringpool* pool, + struct loc_as** as, const struct loc_database_as_v1* dbobj); +int loc_as_to_database_v1(struct loc_as* as, struct loc_stringpool* pool, + struct loc_database_as_v1* dbobj); int loc_as_match_string(struct loc_as* as, const char* string); diff --git a/src/loc/country.h b/src/loc/country.h index 9757b2a..d09daee 100644 --- a/src/loc/country.h +++ b/src/loc/country.h @@ -42,10 +42,10 @@ int loc_country_code_is_valid(const char* cc); #include -int loc_country_new_from_database_v0(struct loc_ctx* ctx, struct loc_stringpool* pool, - struct loc_country** country, const struct loc_database_country_v0* dbobj); -int loc_country_to_database_v0(struct loc_country* country, - struct loc_stringpool* pool, struct loc_database_country_v0* dbobj); +int loc_country_new_from_database_v1(struct loc_ctx* ctx, struct loc_stringpool* pool, + struct loc_country** country, const struct loc_database_country_v1* dbobj); +int loc_country_to_database_v1(struct loc_country* country, + struct loc_stringpool* pool, struct loc_database_country_v1* dbobj); static inline void loc_country_code_copy(char* dst, const char* src) { for (unsigned int i = 0; i < 2; i++) { diff --git a/src/loc/format.h b/src/loc/format.h index 3762c5e..149c999 100644 --- a/src/loc/format.h +++ b/src/loc/format.h @@ -21,12 +21,17 @@ #define LOC_DATABASE_MAGIC "LOCDBXX" +enum loc_database_version { + LOC_DATABASE_VERSION_UNSET = 0, + LOC_DATABASE_VERSION_1 = 1, +}; + #ifdef LIBLOC_PRIVATE -#define LOC_DATABASE_VERSION 0 +#define LOC_DATABASE_VERSION_LATEST LOC_DATABASE_VERSION_1 #define STR(x) #x -#define LOC_DATABASE_DOMAIN_LATEST(version) "_latest._v" STR(version) ".location.ipfire.org" +#define LOC_DATABASE_DOMAIN(version) "_v" STR(version) "._db.location.ipfire.org" #define LOC_DATABASE_PAGE_SIZE 4096 @@ -39,7 +44,7 @@ struct loc_database_magic { uint8_t version; }; -struct loc_database_header_v0 { +struct loc_database_header_v1 { // UNIX timestamp when the database was created uint64_t created_at; @@ -80,14 +85,14 @@ struct loc_database_header_v0 { char padding[32]; }; -struct loc_database_network_node_v0 { +struct loc_database_network_node_v1 { uint32_t zero; uint32_t one; uint32_t network; }; -struct loc_database_network_v0 { +struct loc_database_network_v1 { // The start address and prefix will be encoded in the tree // The country this network is located in @@ -103,7 +108,7 @@ struct loc_database_network_v0 { char padding[2]; }; -struct loc_database_as_v0 { +struct loc_database_as_v1 { // The AS number uint32_t number; @@ -111,7 +116,7 @@ struct loc_database_as_v0 { uint32_t name; }; -struct loc_database_country_v0 { +struct loc_database_country_v1 { char code[2]; char continent_code[2]; diff --git a/src/loc/network.h b/src/loc/network.h index ad43c3a..273041c 100644 --- a/src/loc/network.h +++ b/src/loc/network.h @@ -53,9 +53,9 @@ int loc_network_match_flag(struct loc_network* network, uint32_t flag); #ifdef LIBLOC_PRIVATE -int loc_network_to_database_v0(struct loc_network* network, struct loc_database_network_v0* dbobj); -int loc_network_new_from_database_v0(struct loc_ctx* ctx, struct loc_network** network, - struct in6_addr* address, unsigned int prefix, const struct loc_database_network_v0* dbobj); +int loc_network_to_database_v1(struct loc_network* network, struct loc_database_network_v1* dbobj); +int loc_network_new_from_database_v1(struct loc_ctx* ctx, struct loc_network** network, + struct in6_addr* address, unsigned int prefix, const struct loc_database_network_v1* dbobj); struct loc_network_tree; int loc_network_tree_new(struct loc_ctx* ctx, struct loc_network_tree** tree); diff --git a/src/loc/writer.h b/src/loc/writer.h index 96d14ac..7edaa87 100644 --- a/src/loc/writer.h +++ b/src/loc/writer.h @@ -22,11 +22,13 @@ #include #include #include +#include #include struct loc_writer; -int loc_writer_new(struct loc_ctx* ctx, struct loc_writer** writer, FILE* fkey); +int loc_writer_new(struct loc_ctx* ctx, struct loc_writer** writer, + enum loc_database_version version, FILE* fkey); struct loc_writer* loc_writer_ref(struct loc_writer* writer); struct loc_writer* loc_writer_unref(struct loc_writer* writer); diff --git a/src/network.c b/src/network.c index 8dde0ec..5a8db7a 100644 --- a/src/network.c +++ b/src/network.c @@ -346,7 +346,7 @@ LOC_EXPORT int loc_network_match_flag(struct loc_network* network, uint32_t flag return loc_network_has_flag(network, flag); } -LOC_EXPORT int loc_network_to_database_v0(struct loc_network* network, struct loc_database_network_v0* dbobj) { +LOC_EXPORT int loc_network_to_database_v1(struct loc_network* network, struct loc_database_network_v1* dbobj) { // Add country code loc_country_code_copy(dbobj->country_code, network->country_code); @@ -359,8 +359,8 @@ LOC_EXPORT int loc_network_to_database_v0(struct loc_network* network, struct lo return 0; } -LOC_EXPORT int loc_network_new_from_database_v0(struct loc_ctx* ctx, struct loc_network** network, - struct in6_addr* address, unsigned int prefix, const struct loc_database_network_v0* dbobj) { +LOC_EXPORT int loc_network_new_from_database_v1(struct loc_ctx* ctx, struct loc_network** network, + struct in6_addr* address, unsigned int prefix, const struct loc_database_network_v1* dbobj) { char country_code[3] = "\0\0"; int r = loc_network_new(ctx, network, address, prefix); diff --git a/src/python/location-importer.in b/src/python/location-importer.in index 9e12704..eb4a303 100644 --- a/src/python/location-importer.in +++ b/src/python/location-importer.in @@ -70,6 +70,7 @@ class CLI(object): write.add_argument("--vendor", nargs="?", help=_("Sets the vendor")) write.add_argument("--description", nargs="?", help=_("Sets a description")) write.add_argument("--license", nargs="?", help=_("Sets the license")) + write.add_argument("--version", type=int, help=_("Database Format Version")) # Update WHOIS update_whois = subparsers.add_parser("update-whois", help=_("Update WHOIS Information")) diff --git a/src/python/writer.c b/src/python/writer.c index f708417..6ef9230 100644 --- a/src/python/writer.c +++ b/src/python/writer.c @@ -40,10 +40,11 @@ static void Writer_dealloc(WriterObject* self) { static int Writer_init(WriterObject* self, PyObject* args, PyObject* kwargs) { PyObject* private_key = NULL; + int version = -1; FILE* f = NULL; // Parse arguments - if (!PyArg_ParseTuple(args, "|O", &private_key)) + if (!PyArg_ParseTuple(args, "|Oi", &private_key, &version)) return -1; // Convert into FILE* @@ -61,7 +62,8 @@ static int Writer_init(WriterObject* self, PyObject* args, PyObject* kwargs) { } // Create the writer object - int r = loc_writer_new(loc_ctx, &self->writer, f); + int r = loc_writer_new(loc_ctx, &self->writer, + (enum loc_database_version)version, f); return r; } diff --git a/src/resolv.c b/src/resolv.c index 4c561fb..a213c7f 100644 --- a/src/resolv.c +++ b/src/resolv.c @@ -53,7 +53,7 @@ LOC_EXPORT int loc_discover_latest_version(struct loc_ctx* ctx, const char* doma // Fall back to default domain if (!domain) - domain = LOC_DATABASE_DOMAIN_LATEST(LOC_DATABASE_VERSION); + domain = LOC_DATABASE_DOMAIN(LOC_DATABASE_VERSION_LATEST); unsigned char answer[PACKETSZ]; int len; diff --git a/src/test-as.c b/src/test-as.c index b531173..5357d53 100644 --- a/src/test-as.c +++ b/src/test-as.c @@ -34,7 +34,7 @@ int main(int argc, char** argv) { // Create a database struct loc_writer* writer; - err = loc_writer_new(ctx, &writer, NULL); + err = loc_writer_new(ctx, &writer, LOC_DATABASE_VERSION_LATEST, NULL); if (err < 0) exit(EXIT_FAILURE); diff --git a/src/test-country.c b/src/test-country.c index 4383695..030e78e 100644 --- a/src/test-country.c +++ b/src/test-country.c @@ -49,7 +49,7 @@ int main(int argc, char** argv) { // Create a database struct loc_writer* writer; - err = loc_writer_new(ctx, &writer, NULL); + err = loc_writer_new(ctx, &writer, LOC_DATABASE_VERSION_LATEST, NULL); if (err < 0) exit(EXIT_FAILURE); diff --git a/src/test-database.c b/src/test-database.c index 228567b..f4e8e6b 100644 --- a/src/test-database.c +++ b/src/test-database.c @@ -47,7 +47,7 @@ int main(int argc, char** argv) { // Create a database struct loc_writer* writer; - err = loc_writer_new(ctx, &writer, NULL); + err = loc_writer_new(ctx, &writer, LOC_DATABASE_VERSION_LATEST, NULL); if (err < 0) exit(EXIT_FAILURE); diff --git a/src/test-network.c b/src/test-network.c index 9a74566..244eb75 100644 --- a/src/test-network.c +++ b/src/test-network.c @@ -93,7 +93,7 @@ int main(int argc, char** argv) { // Create a database struct loc_writer* writer; - err = loc_writer_new(ctx, &writer, NULL); + err = loc_writer_new(ctx, &writer, LOC_DATABASE_VERSION_LATEST, NULL); if (err < 0) exit(EXIT_FAILURE); diff --git a/src/test-signature.c b/src/test-signature.c index 4401f43..aacd763 100644 --- a/src/test-signature.c +++ b/src/test-signature.c @@ -51,7 +51,7 @@ int main(int argc, char** argv) { // Create an empty database struct loc_writer* writer; - err = loc_writer_new(ctx, &writer, private_key); + err = loc_writer_new(ctx, &writer, LOC_DATABASE_VERSION_LATEST, private_key); if (err < 0) exit(EXIT_FAILURE); diff --git a/src/writer.c b/src/writer.c index 6cd0027..bccfd43 100644 --- a/src/writer.c +++ b/src/writer.c @@ -44,6 +44,7 @@ struct loc_writer { struct loc_ctx* ctx; int refcount; + enum loc_database_version version; struct loc_stringpool* pool; off_t vendor; @@ -81,7 +82,8 @@ static int parse_private_key(struct loc_writer* writer, FILE* f) { return 0; } -LOC_EXPORT int loc_writer_new(struct loc_ctx* ctx, struct loc_writer** writer, FILE* fkey) { +LOC_EXPORT int loc_writer_new(struct loc_ctx* ctx, struct loc_writer** writer, + enum loc_database_version version, FILE* fkey) { struct loc_writer* w = calloc(1, sizeof(*w)); if (!w) return -ENOMEM; @@ -89,6 +91,22 @@ LOC_EXPORT int loc_writer_new(struct loc_ctx* ctx, struct loc_writer** writer, F w->ctx = loc_ref(ctx); w->refcount = 1; + // Check version + switch (version) { + case LOC_DATABASE_VERSION_1: + w->version = version; + break; + + case LOC_DATABASE_VERSION_UNSET: + w->version = LOC_DATABASE_VERSION_LATEST; + break; + + default: + ERROR(ctx, "Invalid database version: %d\n", version); + loc_writer_unref(w); + return -1; + } + int r = loc_stringpool_new(ctx, &w->pool); if (r) { loc_writer_unref(w); @@ -265,7 +283,7 @@ static void make_magic(struct loc_writer* writer, struct loc_database_magic* mag magic->magic[i] = LOC_DATABASE_MAGIC[i]; // Set version - magic->version = htobe16(LOC_DATABASE_VERSION); + magic->version = htobe16(writer->version); } static void align_page_boundary(off_t* offset, FILE* f) { @@ -275,7 +293,7 @@ static void align_page_boundary(off_t* offset, FILE* f) { } static int loc_database_write_pool(struct loc_writer* writer, - struct loc_database_header_v0* header, off_t* offset, FILE* f) { + struct loc_database_header_v1* header, off_t* offset, FILE* f) { // Save the offset of the pool section DEBUG(writer->ctx, "Pool starts at %jd bytes\n", (intmax_t)*offset); header->pool_offset = htobe32(*offset); @@ -291,16 +309,16 @@ static int loc_database_write_pool(struct loc_writer* writer, } static int loc_database_write_as_section(struct loc_writer* writer, - struct loc_database_header_v0* header, off_t* offset, FILE* f) { + struct loc_database_header_v1* header, off_t* offset, FILE* f) { DEBUG(writer->ctx, "AS section starts at %jd bytes\n", (intmax_t)*offset); header->as_offset = htobe32(*offset); size_t as_length = 0; - struct loc_database_as_v0 as; + struct loc_database_as_v1 as; for (unsigned int i = 0; i < writer->as_count; i++) { // Convert AS into database format - loc_as_to_database_v0(writer->as[i], writer->pool, &as); + loc_as_to_database_v1(writer->as[i], writer->pool, &as); // Write to disk *offset += fwrite(&as, 1, sizeof(as), f); @@ -365,7 +383,7 @@ static void free_network(struct network* network) { } static int loc_database_write_networks(struct loc_writer* writer, - struct loc_database_header_v0* header, off_t* offset, FILE* f) { + struct loc_database_header_v1* header, off_t* offset, FILE* f) { // Write the network tree DEBUG(writer->ctx, "Network tree starts at %jd bytes\n", (intmax_t)*offset); header->network_tree_offset = htobe32(*offset); @@ -379,8 +397,8 @@ static int loc_database_write_networks(struct loc_writer* writer, uint32_t index = 0; uint32_t network_index = 0; - struct loc_database_network_v0 db_network; - struct loc_database_network_node_v0 db_node; + struct loc_database_network_v1 db_network; + struct loc_database_network_node_v1 db_node; // Initialize queue for nodes TAILQ_HEAD(node_t, node) nodes; @@ -467,7 +485,7 @@ static int loc_database_write_networks(struct loc_writer* writer, TAILQ_REMOVE(&networks, nw, networks); // Prepare what we are writing to disk - int r = loc_network_to_database_v0(nw->network, &db_network); + int r = loc_network_to_database_v1(nw->network, &db_network); if (r) return r; @@ -485,16 +503,16 @@ static int loc_database_write_networks(struct loc_writer* writer, } static int loc_database_write_countries(struct loc_writer* writer, - struct loc_database_header_v0* header, off_t* offset, FILE* f) { + struct loc_database_header_v1* header, off_t* offset, FILE* f) { DEBUG(writer->ctx, "Countries section starts at %jd bytes\n", (intmax_t)*offset); header->countries_offset = htobe32(*offset); size_t countries_length = 0; - struct loc_database_country_v0 country; + struct loc_database_country_v1 country; for (unsigned int i = 0; i < writer->countries_count; i++) { // Convert country into database format - loc_country_to_database_v0(writer->countries[i], writer->pool, &country); + loc_country_to_database_v1(writer->countries[i], writer->pool, &country); // Write to disk *offset += fwrite(&country, 1, sizeof(country), f); @@ -510,7 +528,7 @@ static int loc_database_write_countries(struct loc_writer* writer, } static int loc_writer_create_signature(struct loc_writer* writer, - struct loc_database_header_v0* header, FILE* f) { + struct loc_database_header_v1* header, FILE* f) { DEBUG(writer->ctx, "Signing database...\n"); // Read file from the beginning @@ -602,7 +620,7 @@ LOC_EXPORT int loc_writer_write(struct loc_writer* writer, FILE* f) { make_magic(writer, &magic); // Make the header - struct loc_database_header_v0 header; + struct loc_database_header_v1 header; header.vendor = htobe32(writer->vendor); header.description = htobe32(writer->description); header.license = htobe32(writer->license); -- 2.39.2