1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/*
* src/database.c
* (c) 2021 Jonas Gunz <himself@jonasgunz.de>
* License: MIT
*/
#include "database.h"
static int database_init ( database_t* _database ) {
unsigned int i = 0;
size_t rr_size;
/* Initialize 2D array of tree_node pointers, paranoia style */
if ( !( _database->zone = malloc( sizeof( tree_node_t** ) * DB_CLASS_LEN ) ) )
return 1;
rr_size = sizeof( struct tree_node* ) * DB_RR_LEN;
for ( 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 ( database_t* _database, char* _zonefile ) {
char* qname;
int len;
void* data;
if ( database_init( _database ) ) {
LOGPRINTF(_LOG_ERROR, "Failed to initialize database.");
return 1;
}
/* TODO parsing */
qname = malloc(32);
len = fqdn_to_qname( "test.example.com", 17, qname, 32 );
if ( len <= 0 )
return 1;
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 );
LOGPRINTF(_LOG_NOTE, "Database initialized and populated");
return 0;
}
int database_destroy ( database_t* _database ) {
unsigned int i, o;
if ( !_database || !_database->zone )
return 1;
for ( i = 0; i < DB_CLASS_LEN; i++ ) {
for ( 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 (
database_rdata_t* _rdata,
database_t* _database,
const char* _qname,
int _qname_len,
uint16_t _qtype,
uint16_t _qclass
) {
uint16_t type, class;
void* data;
/* _qtype and _qclass start at 1, so they are invalid when 0. */
if ( !_rdata || !_database || !_qname || !_qtype || !_qclass || _qname_len <= 0 ) {
LOGPRINTF(_LOG_ERROR, "Invalid arguments");
return 1;
}
if ( _qtype >= DB_RR_LEN || _qclass >= DB_RR_LEN ) {
LOGPRINTF(_LOG_DEBUG, "Invalid qtype/qclass");
return 1;
}
_rdata->ttl = 0;
_rdata->rdlen = 0;
_rdata->rdata = NULL;
type = _qtype - 1;
class = _qclass - 1;
data = tree_get( &_database->zone[class][type], _qname );
if ( !data ) {
LOGPRINTF(_LOG_DEBUG, "No matching RR found");
return 2;
}
_rdata->ttl = *( (uint32_t*) data );
_rdata->rdlen = *( (uint16_t*)(data + 4) );
_rdata->rdata = data + 6;
return 0;
}
|