ARPA2 Common Libraries  2.6.2
rules_db.h
1 
35 /*
36  * SPDX-License-Identifier: BSD-2-Clause
37  * SPDX-FileCopyrightText: Copyright 2020 Rick van Rein <rick@openfortress.nl>
38  */
39 
40 
41 #ifndef ARPA2_RULES_DB_H
42 #define ARPA2_RULES_DB_H
43 
44 
45 #include <stdlib.h>
46 #include <stdint.h>
47 #include <stdbool.h>
48 
49 #include <lmdb.h>
50 
51 #include <arpa2/digest.h>
52 #include <arpa2/identity.h>
53 
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 
60 // A few good sources on LMDB knowledge:
61 //
62 // https://blogs.kolabnow.com/2018/06/07/a-short-guide-to-lmdb
63 // http://www.lmdb.tech/doc/starting.html
64 // https://github.com/LMDB/lmdb/blob/mdb.master/libraries/liblmdb/lmdb.h
65 
66 
138 #ifdef RULES_TIGHT_LMDBKEY
139  typedef unsigned int rules_dbkey_lmdbkey;
140  typedef uint8_t rules_dbkey [A2MD_OUTPUT_SIZE]
141  __attribute__((__aligned__(4)));
142 #else /* !RULES_TIGHT_LMDBKEY */
143  typedef size_t rules_dbkey_lmdbkey;
144  typedef uint8_t rules_dbkey [A2MD_OUTPUT_SIZE]
145  __attribute__((__aligned__(8)));
146 #endif /* RULES_TIGHT_LMDBKEY */
147 
168 #define RULES_LMDBKEY_SIZE (sizeof (rules_dbkey_lmdbkey))
169 #define RULES_RESTKEY_SIZE (A2MD_OUTPUT_SIZE - RULES_LMDBKEY_SIZE)
170 
171 #define digest2lmdbkey(digest) ((rules_dbkey_lmdbkey *) ((uint8_t *) digest))
172 #define digest2restkey(digest) (((uint8_t *) digest) + RULES_LMDBKEY_SIZE)
173 
174 
192 #ifndef RULES_ENVIRONMENT_PATH
193 #define RULES_ENVIRONMENT_PATH "/var/lib/arpa2/rules/"
194 #endif
195 
196 #ifndef RULES_DATABASE_NAME
197 #define RULES_DATABASE_NAME "RuleDB"
198 #endif
199 
200 #ifndef RULES_DATABASE_SIZE
201 #define RULES_DATABASE_SIZE 1048576000L
202 #endif
203 
204 #ifndef RULES_DATABASE_COUNT_MAX
205 #define RULES_DATABASE_COUNT_MAX 10
206 #endif
207 
208 
209 
210 //TODO//TESTPROGRAM// assert (sizeof (rules_dbkey) == A2MD_OUTPUT_SIZE);
211 
212 
227 #define RULES_TRUNK_ANY 0
228 #define RULES_TRUNK_MIN 1
229 #define RULES_TRUNK_MAX 4294967295
230 #define RULES_TRUNK_SIZE 4
231 
232 
235 typedef union {
236  uint8_t netbytes [RULES_TRUNK_SIZE];
237  uint32_t netint32;
238 } rules_trunk;
239 
240 
248 struct rules_db {
249  MDB_env *env;
250  MDB_txn *txn;
251  MDB_dbi dbi;
252  MDB_cursor *crs;
253  rules_dbkey dig;
254  bool got;
255  rules_trunk trk;
256 };
257 
258 
260 // And another... probably due to upsetting __attribute__((__aligned__())) above
271 bool rules_dbrollback (struct rules_db *ruledb);
272 
273 
276 bool rules_dbcommit (struct rules_db *ruledb);
277 
278 
281 bool rules_dbsuspend (struct rules_db *ruledb);
282 
283 
286 bool rules_dbresume (struct rules_db *ruledb);
287 
288 
301 bool rules_dbopen (struct rules_db *ruledb, bool rdonly, uint32_t trunk);
302 
303 
310 static inline bool rules_dbopen_rdonly (struct rules_db *ruledb) {
311  return rules_dbopen (ruledb, true, RULES_TRUNK_ANY);
312 }
313 
314 
317 bool rules_dbclose (struct rules_db *ruledb);
318 
319 
347 static inline bool rules_dbnext (const MDB_val *dbdata, char **rule) {
348  *rule += strlen (*rule) + 1;
349  return ((*rule) < ((char *) dbdata->mv_data) + dbdata->mv_size);
350 }
358 static inline bool rules_dbloop (const MDB_val *dbdata, char **rule) {
359  *rule = (char *) dbdata->mv_data;
360  return (dbdata->mv_size > 0);
361 }
377 static inline bool rules_dbcutnext (MDB_val *dbdata, char **rule, bool cutrule) {
378  if (!cutrule) {
379  return rules_dbnext (dbdata, rule);
380  }
381  unsigned rulelen = strlen (*rule) + 1;
382  char *tail = *rule + rulelen;
383  unsigned taillen = ((char *) dbdata->mv_data) + dbdata->mv_size - tail;
384  if (taillen > 0) {
385  memmove (*rule, tail, taillen);
386  }
387  dbdata->mv_size -= rulelen;
388  return (taillen > 0);
389 }
390 
391 
411 bool rules_dbget (struct rules_db *ruledb, rules_dbkey digkey, MDB_val *out_dbdata);
412 
413 
455 typedef enum { do_add, do_del } changerules_what;
456 //
457 bool rules_edit_generic (rules_dbkey svckey, unsigned svckeylen,
458  char *xsname,
459  char *rules, unsigned ruleslen,
460  changerules_what whattodo,
461  a2sel_t *opt_selector, struct rules_db *opt_nested);
462 
463 
477 static inline bool rules_dbadd (rules_dbkey prekey, unsigned prekeylen,
478  char *xskey,
479  char *rules, unsigned ruleslen, a2sel_t *opt_selector) {
480  return rules_edit_generic (prekey, prekeylen, xskey, rules, ruleslen,
481  do_add, opt_selector, NULL);
482 }
483 
484 
498 static inline bool rules_dbdel (rules_dbkey prekey, unsigned prekeylen,
499  char *xskey,
500  char *rules, unsigned ruleslen, a2sel_t *opt_selector) {
501  return rules_edit_generic (prekey, prekeylen, xskey, rules, ruleslen,
502  do_del, opt_selector, NULL);
503 }
504 
505 
537 bool rules_dbset (struct rules_db *ruledb, MDB_val *in0_dbdata, MDB_val *in1_dbdata);
538 
539 
615 bool rules_dbkey_domain (rules_dbkey domkey,
616  const uint8_t *opt_dbkey, int dbkeylen,
617  const char *xsdomain);
618 
619 
645 bool rules_dbkey_service (rules_dbkey svckey,
646  const uint8_t *domkey, unsigned domkeylen,
647  const uint8_t xstype [16]);
648 
649 
684 bool rules_dbkey_selector (rules_dbkey reqkey,
685  const uint8_t *svckey, unsigned svckeylen,
686  const char *xsname,
687  const a2sel_t *selector);
688 
689 
710 bool rules_dbkey_parse (rules_dbkey outkey,
711  const char *hexkey, int hexkeylen);
712 
713 
716 #ifdef __cplusplus
717 }
718 #endif
719 
720 #endif /* ARPA2_RULES_DB_H */
721 
size_t rules_dbkey_lmdbkey
Integer value for the LMDB lookup key (beginning of rules_dbkey)
Definition: rules_db.h:143
#define RULES_TRUNK_ANY
Wildcard value for trunk identities.
Definition: rules_db.h:227
#define RULES_TRUNK_SIZE
Trunk identities are stored in 32 bits.
Definition: rules_db.h:230
bool rules_dbresume(struct rules_db *ruledb)
Resume reading from the ACL databaes.
bool rules_dbsuspend(struct rules_db *ruledb)
Suspend reading from the ACL database.
bool rules_dbrollback(struct rules_db *ruledb)
Rollback recent writes to the ACL database.
bool rules_dbopen(struct rules_db *ruledb, bool rdonly, uint32_t trunk)
Open the ACL database, possibly for bulk updates.
static bool rules_dbopen_rdonly(struct rules_db *ruledb)
Open the ACL database for reading.
Definition: rules_db.h:310
bool rules_dbcommit(struct rules_db *ruledb)
Commit recent changes to the ACL database.
bool rules_dbclose(struct rules_db *ruledb)
Close the ACL database.
static bool rules_dbadd(rules_dbkey prekey, unsigned prekeylen, char *xskey, char *rules, unsigned ruleslen, a2sel_t *opt_selector)
Add rules to the database.
Definition: rules_db.h:477
changerules_what
Whether to add or delete rules in the ruleset.
Definition: rules_db.h:455
static bool rules_dbnext(const MDB_val *dbdata, char **rule)
Next in iteration over a ruleset, started with rules_dbloop().
Definition: rules_db.h:347
bool rules_dbset(struct rules_db *ruledb, MDB_val *in0_dbdata, MDB_val *in1_dbdata)
Set rules in the RuleDB.
static bool rules_dbcutnext(MDB_val *dbdata, char **rule, bool cutrule)
While iterating over a ruleset, possible remove the current rule before focussing on the next rule....
Definition: rules_db.h:377
static bool rules_dbloop(const MDB_val *dbdata, char **rule)
Start iteration over a ruleset, continue with rules_dbnext().
Definition: rules_db.h:358
static bool rules_dbdel(rules_dbkey prekey, unsigned prekeylen, char *xskey, char *rules, unsigned ruleslen, a2sel_t *opt_selector)
Delete rules from the database.
Definition: rules_db.h:498
bool rules_dbget(struct rules_db *ruledb, rules_dbkey digkey, MDB_val *out_dbdata)
Get rules from the RuleDB.
bool rules_dbkey_domain(rules_dbkey domkey, const uint8_t *opt_dbkey, int dbkeylen, const char *xsdomain)
Derive the Domain Key for a given domain name and optional Database Secret.
bool rules_dbkey_parse(rules_dbkey outkey, const char *hexkey, int hexkeylen)
Parse a Database Key from hexidecimal notation.
bool rules_dbkey_selector(rules_dbkey reqkey, const uint8_t *svckey, unsigned svckeylen, const char *xsname, const a2sel_t *selector)
Derive the Request Key for a given Access Name and Selector, using a Domain Key as a start....
bool rules_dbkey_service(rules_dbkey svckey, const uint8_t *domkey, unsigned domkeylen, const uint8_t xstype[16])
Derive the Service Key for a given Access Type, using a Domain Key as a start.
ARPA2 Selector.
Definition: identity.h:165
The RuleDB structure keeps track of LMDB control.
Definition: rules_db.h:248
Trunk identities are stored as 4-byte values in network order.
Definition: rules_db.h:235