aboutsummaryrefslogtreecommitdiff
path: root/src/database.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/database.c')
-rw-r--r--src/database.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/database.c b/src/database.c
new file mode 100644
index 0000000..a684cff
--- /dev/null
+++ b/src/database.c
@@ -0,0 +1,106 @@
+/*
+ * src/database.c
+ * (c) 2021 Jonas Gunz <himself@jonasgunz.de>
+ * License: MIT
+ */
+
+#include "database.h"
+
+static int database_init ( struct database* _database ) {
+ // Initialize 2D array of tree_node pointers, paranoia style
+ if ( !( _database->zone = malloc( sizeof( struct tree_node** ) * DB_CLASS_LEN ) ) )
+ return 1;
+
+ size_t rr_size = sizeof( struct tree_node* ) * DB_RR_LEN;
+ for ( unsigned int i = 0; i < DB_CLASS_LEN; i++ ) {
+ if ( !( _database->zone[i] = malloc( rr_size ) ) )
+ return 1;
+
+ memset( _database->zone[i], 0, rr_size );
+ }
+
+ return 0;
+}
+
+int database_populate (
+ struct database* _database,
+ char* _zonefile
+) {
+ if ( database_init( _database ) )
+ return 1;
+
+ // TODO parsing
+
+ char* qname = malloc(32);
+
+ int len = fqdn_to_qname( "test.example.com", 17, qname, 32 );
+
+ if ( len <= 0 )
+ return 1;
+
+ void* data = malloc( 10 );
+
+ *((uint32_t*)data) = 1800;
+ *((uint16_t*)(data+4)) = 4;
+ *((uint32_t*)(data+6)) = 0x45454545;
+
+ tree_insert( &_database->zone[0][0], qname, data );
+
+ return 0;
+}
+
+int database_destroy ( struct database* _database ) {
+ if ( !_database || !_database->zone )
+ return 1;
+
+ for ( unsigned int i = 0; i < DB_CLASS_LEN; i++ ) {
+ for ( unsigned int o = 0; o < DB_RR_LEN; o++ ) {
+ // TODO should we free data and key?
+ tree_destroy( &_database->zone[i][o], _TREE_FREE_DATA | _TREE_FREE_KEY );
+ }
+
+ free( _database->zone[i] );
+ }
+
+ free( _database->zone );
+ _database->zone = NULL;
+
+ return 1;
+}
+
+int database_query (
+ struct database_rdata* _rdata,
+ struct database* _database,
+ const char* _qname,
+ int _qname_len,
+ uint16_t _qtype,
+ uint16_t _qclass
+) {
+ uint16_t type, class;
+
+ // _qtype and _qclass start at 1, so they are invalid when 0.
+
+ if ( !_rdata || !_database || !_qname || !_qtype || !_qclass || _qname_len <= 0 )
+ return 1;
+
+ if ( _qtype >= DB_RR_LEN || _qclass >= DB_RR_LEN )
+ return 1;
+
+ _rdata->ttl = 0;
+ _rdata->rdlen = 0;
+ _rdata->rdata = NULL;
+
+ type = _qtype - 1;
+ class = _qclass - 1;
+
+ void* data = tree_get( &_database->zone[class][type], _qname );
+
+ if ( !data )
+ return 2;
+
+ _rdata->ttl = *( (uint32_t*) data );
+ _rdata->rdlen = *( (uint16_t*)(data + 4) );
+ _rdata->rdata = data + 6;
+
+ return 0;
+}