amduatd: add opt-in federation config, space scoping, and tests
This commit is contained in:
parent
db3c4b4c93
commit
af11665a35
|
|
@ -26,7 +26,8 @@ target_link_libraries(amduat_federation
|
||||||
|
|
||||||
set(amduatd_sources src/amduatd.c src/amduatd_http.c src/amduatd_caps.c
|
set(amduatd_sources src/amduatd.c src/amduatd_http.c src/amduatd_caps.c
|
||||||
src/amduatd_space.c src/amduatd_concepts.c
|
src/amduatd_space.c src/amduatd_concepts.c
|
||||||
src/amduatd_store.c src/amduatd_derivation_index.c)
|
src/amduatd_store.c src/amduatd_derivation_index.c
|
||||||
|
src/amduatd_fed.c)
|
||||||
if(AMDUATD_ENABLE_UI)
|
if(AMDUATD_ENABLE_UI)
|
||||||
list(APPEND amduatd_sources src/amduatd_ui.c)
|
list(APPEND amduatd_sources src/amduatd_ui.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
@ -117,3 +118,21 @@ target_link_libraries(amduatd_test_derivation_index
|
||||||
)
|
)
|
||||||
|
|
||||||
add_test(NAME amduatd_derivation_index COMMAND amduatd_test_derivation_index)
|
add_test(NAME amduatd_derivation_index COMMAND amduatd_test_derivation_index)
|
||||||
|
|
||||||
|
add_executable(amduatd_test_fed_cfg
|
||||||
|
tests/test_amduatd_fed_cfg.c
|
||||||
|
src/amduatd_fed.c
|
||||||
|
src/amduatd_space.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(amduatd_test_fed_cfg
|
||||||
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/vendor/amduat/include
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(amduatd_test_fed_cfg
|
||||||
|
PRIVATE amduat_asl amduat_enc amduat_util amduat_asl_pointer_fs
|
||||||
|
)
|
||||||
|
|
||||||
|
add_test(NAME amduatd_fed_cfg COMMAND amduatd_test_fed_cfg)
|
||||||
|
|
|
||||||
24
README.md
24
README.md
|
|
@ -47,6 +47,30 @@ Run the daemon with the index-backed store:
|
||||||
|
|
||||||
Note: `/v1/fed/records` requires the index backend.
|
Note: `/v1/fed/records` requires the index backend.
|
||||||
|
|
||||||
|
## Federation (dev)
|
||||||
|
|
||||||
|
Federation is opt-in and disabled by default. Enabling federation requires the
|
||||||
|
index-backed store and explicit flags:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./build/amduatd --root .amduat-asl --sock amduatd.sock --store-backend index \
|
||||||
|
--fed-enable --fed-transport unix --fed-unix-sock peer.sock \
|
||||||
|
--fed-domain-id 1 --fed-registry-ref <registry_ref_hex>
|
||||||
|
```
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
|
||||||
|
- `--fed-enable` turns on the coordinator tick loop.
|
||||||
|
- `--fed-transport stub|unix` selects transport (`stub` by default).
|
||||||
|
- `--fed-unix-sock PATH` configures the unix transport socket path.
|
||||||
|
- `--fed-domain-id ID` sets the local domain id.
|
||||||
|
- `--fed-registry-ref REF` seeds the registry reference (hex ref).
|
||||||
|
- `--fed-require-space` rejects `/v1/fed/*` requests that do not resolve a space.
|
||||||
|
|
||||||
|
`X-Amduat-Space` is honored for `/v1/fed/*` requests the same way as other
|
||||||
|
endpoints. If `--space` is configured, unix transport requests will include the
|
||||||
|
same `X-Amduat-Space` header when contacting peers.
|
||||||
|
|
||||||
Run the daemon with derivation indexing enabled:
|
Run the daemon with derivation indexing enabled:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|
|
||||||
|
|
@ -687,7 +687,9 @@ static int amduat_fed_transport_unix_get_records(void *ctx,
|
||||||
amduat_fed_record_t **out_records,
|
amduat_fed_record_t **out_records,
|
||||||
size_t *out_len) {
|
size_t *out_len) {
|
||||||
amduat_fed_transport_unix_t *transport = (amduat_fed_transport_unix_t *)ctx;
|
amduat_fed_transport_unix_t *transport = (amduat_fed_transport_unix_t *)ctx;
|
||||||
char req[512];
|
char req[2048];
|
||||||
|
char space_header[AMDUAT_ASL_POINTER_NAME_MAX + 32u];
|
||||||
|
const char *space_line = "";
|
||||||
int fd;
|
int fd;
|
||||||
uint8_t *buf = NULL;
|
uint8_t *buf = NULL;
|
||||||
size_t buf_len = 0;
|
size_t buf_len = 0;
|
||||||
|
|
@ -703,13 +705,23 @@ static int amduat_fed_transport_unix_get_records(void *ctx,
|
||||||
*out_records = NULL;
|
*out_records = NULL;
|
||||||
*out_len = 0;
|
*out_len = 0;
|
||||||
|
|
||||||
|
if (transport->has_space) {
|
||||||
|
snprintf(space_header,
|
||||||
|
sizeof(space_header),
|
||||||
|
"X-Amduat-Space: %s\r\n",
|
||||||
|
transport->space_id);
|
||||||
|
space_line = space_header;
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(req, sizeof(req),
|
snprintf(req, sizeof(req),
|
||||||
"GET /v1/fed/records?domain_id=%u&from_logseq=%llu HTTP/1.1\r\n"
|
"GET /v1/fed/records?domain_id=%u&from_logseq=%llu HTTP/1.1\r\n"
|
||||||
"Host: localhost\r\n"
|
"Host: localhost\r\n"
|
||||||
|
"%s"
|
||||||
"Connection: close\r\n"
|
"Connection: close\r\n"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
(unsigned int)domain_id,
|
(unsigned int)domain_id,
|
||||||
(unsigned long long)from_logseq);
|
(unsigned long long)from_logseq,
|
||||||
|
space_line);
|
||||||
|
|
||||||
fd = amduat_fed_transport_unix_connect(transport->socket_path);
|
fd = amduat_fed_transport_unix_connect(transport->socket_path);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
|
@ -767,7 +779,9 @@ static int amduat_fed_transport_unix_get_artifact(void *ctx,
|
||||||
amduat_octets_t *out_bytes) {
|
amduat_octets_t *out_bytes) {
|
||||||
amduat_fed_transport_unix_t *transport = (amduat_fed_transport_unix_t *)ctx;
|
amduat_fed_transport_unix_t *transport = (amduat_fed_transport_unix_t *)ctx;
|
||||||
char *ref_hex = NULL;
|
char *ref_hex = NULL;
|
||||||
char req[512];
|
char req[2048];
|
||||||
|
char space_header[AMDUAT_ASL_POINTER_NAME_MAX + 32u];
|
||||||
|
const char *space_line = "";
|
||||||
int fd;
|
int fd;
|
||||||
uint8_t *buf = NULL;
|
uint8_t *buf = NULL;
|
||||||
size_t buf_len = 0;
|
size_t buf_len = 0;
|
||||||
|
|
@ -783,12 +797,21 @@ static int amduat_fed_transport_unix_get_artifact(void *ctx,
|
||||||
if (!amduat_asl_ref_encode_hex(ref, &ref_hex)) {
|
if (!amduat_asl_ref_encode_hex(ref, &ref_hex)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (transport->has_space) {
|
||||||
|
snprintf(space_header,
|
||||||
|
sizeof(space_header),
|
||||||
|
"X-Amduat-Space: %s\r\n",
|
||||||
|
transport->space_id);
|
||||||
|
space_line = space_header;
|
||||||
|
}
|
||||||
snprintf(req, sizeof(req),
|
snprintf(req, sizeof(req),
|
||||||
"GET /v1/fed/artifacts/%s HTTP/1.1\r\n"
|
"GET /v1/fed/artifacts/%s HTTP/1.1\r\n"
|
||||||
"Host: localhost\r\n"
|
"Host: localhost\r\n"
|
||||||
|
"%s"
|
||||||
"Connection: close\r\n"
|
"Connection: close\r\n"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
ref_hex);
|
ref_hex,
|
||||||
|
space_line);
|
||||||
free(ref_hex);
|
free(ref_hex);
|
||||||
|
|
||||||
fd = amduat_fed_transport_unix_connect(transport->socket_path);
|
fd = amduat_fed_transport_unix_connect(transport->socket_path);
|
||||||
|
|
@ -837,6 +860,34 @@ bool amduat_fed_transport_unix_init(amduat_fed_transport_unix_t *transport,
|
||||||
memset(transport->socket_path, 0, sizeof(transport->socket_path));
|
memset(transport->socket_path, 0, sizeof(transport->socket_path));
|
||||||
strncpy(transport->socket_path, socket_path,
|
strncpy(transport->socket_path, socket_path,
|
||||||
AMDUAT_FED_TRANSPORT_UNIX_PATH_MAX - 1u);
|
AMDUAT_FED_TRANSPORT_UNIX_PATH_MAX - 1u);
|
||||||
|
memset(transport->space_id, 0, sizeof(transport->space_id));
|
||||||
|
transport->has_space = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduat_fed_transport_unix_set_space(amduat_fed_transport_unix_t *transport,
|
||||||
|
const char *space_id) {
|
||||||
|
size_t len;
|
||||||
|
size_t i;
|
||||||
|
if (transport == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset(transport->space_id, 0, sizeof(transport->space_id));
|
||||||
|
transport->has_space = false;
|
||||||
|
if (space_id == NULL || space_id[0] == '\0') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
len = strlen(space_id);
|
||||||
|
if (len >= sizeof(transport->space_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; ++i) {
|
||||||
|
if (space_id[i] == '\r' || space_id[i] == '\n') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memcpy(transport->space_id, space_id, len);
|
||||||
|
transport->has_space = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#define AMDUAT_FED_TRANSPORT_UNIX_H
|
#define AMDUAT_FED_TRANSPORT_UNIX_H
|
||||||
|
|
||||||
#include "federation/coord.h"
|
#include "federation/coord.h"
|
||||||
|
#include "amduat/asl/asl_pointer_fs.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
@ -11,11 +12,16 @@ enum { AMDUAT_FED_TRANSPORT_UNIX_PATH_MAX = 1024 };
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char socket_path[AMDUAT_FED_TRANSPORT_UNIX_PATH_MAX];
|
char socket_path[AMDUAT_FED_TRANSPORT_UNIX_PATH_MAX];
|
||||||
|
char space_id[AMDUAT_ASL_POINTER_NAME_MAX + 1u];
|
||||||
|
bool has_space;
|
||||||
} amduat_fed_transport_unix_t;
|
} amduat_fed_transport_unix_t;
|
||||||
|
|
||||||
bool amduat_fed_transport_unix_init(amduat_fed_transport_unix_t *transport,
|
bool amduat_fed_transport_unix_init(amduat_fed_transport_unix_t *transport,
|
||||||
const char *socket_path);
|
const char *socket_path);
|
||||||
|
|
||||||
|
bool amduat_fed_transport_unix_set_space(amduat_fed_transport_unix_t *transport,
|
||||||
|
const char *space_id);
|
||||||
|
|
||||||
amduat_fed_transport_t amduat_fed_transport_unix_ops(
|
amduat_fed_transport_t amduat_fed_transport_unix_ops(
|
||||||
amduat_fed_transport_unix_t *transport);
|
amduat_fed_transport_unix_t *transport);
|
||||||
|
|
||||||
|
|
|
||||||
134
src/amduatd.c
134
src/amduatd.c
|
|
@ -26,6 +26,7 @@
|
||||||
#include "amduat/tgk/core.h"
|
#include "amduat/tgk/core.h"
|
||||||
#include "federation/coord.h"
|
#include "federation/coord.h"
|
||||||
#include "federation/transport_stub.h"
|
#include "federation/transport_stub.h"
|
||||||
|
#include "federation/transport_unix.h"
|
||||||
#include "amduat/pel/program_dag.h"
|
#include "amduat/pel/program_dag.h"
|
||||||
#include "amduat/pel/program_dag_desc.h"
|
#include "amduat/pel/program_dag_desc.h"
|
||||||
#include "amduat/pel/opreg_kernel.h"
|
#include "amduat/pel/opreg_kernel.h"
|
||||||
|
|
@ -38,6 +39,7 @@
|
||||||
#include "amduatd_ui.h"
|
#include "amduatd_ui.h"
|
||||||
#include "amduatd_caps.h"
|
#include "amduatd_caps.h"
|
||||||
#include "amduatd_space.h"
|
#include "amduatd_space.h"
|
||||||
|
#include "amduatd_fed.h"
|
||||||
#include "amduatd_store.h"
|
#include "amduatd_store.h"
|
||||||
#include "amduatd_derivation_index.h"
|
#include "amduatd_derivation_index.h"
|
||||||
|
|
||||||
|
|
@ -975,8 +977,37 @@ static bool amduatd_parse_u32_str(const char *s, uint32_t *out) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool amduatd_fed_require_space(int fd,
|
||||||
|
const amduatd_fed_cfg_t *fed_cfg,
|
||||||
|
const amduatd_http_req_t *req) {
|
||||||
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
|
const char *err = NULL;
|
||||||
|
char msg[128];
|
||||||
|
|
||||||
|
if (fed_cfg == NULL || req == NULL) {
|
||||||
|
return amduatd_http_send_text(fd, 500, "Internal Server Error",
|
||||||
|
"internal error\n", false);
|
||||||
|
}
|
||||||
|
if (!amduatd_fed_scope_names(fed_cfg,
|
||||||
|
req->effective_space,
|
||||||
|
"fed",
|
||||||
|
&scoped,
|
||||||
|
&err)) {
|
||||||
|
const char *reason = err != NULL ? err : "invalid X-Amduat-Space";
|
||||||
|
int n = snprintf(msg, sizeof(msg), "%s\n", reason);
|
||||||
|
if (n <= 0 || (size_t)n >= sizeof(msg)) {
|
||||||
|
return amduatd_http_send_text(fd, 400, "Bad Request",
|
||||||
|
"invalid X-Amduat-Space\n", false);
|
||||||
|
}
|
||||||
|
return amduatd_http_send_text(fd, 400, "Bad Request", msg, false);
|
||||||
|
}
|
||||||
|
amduat_octets_free(&scoped);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool amduatd_handle_get_fed_records(int fd,
|
static bool amduatd_handle_get_fed_records(int fd,
|
||||||
amduat_asl_store_t *store,
|
amduat_asl_store_t *store,
|
||||||
|
const amduatd_fed_cfg_t *fed_cfg,
|
||||||
const amduatd_http_req_t *req) {
|
const amduatd_http_req_t *req) {
|
||||||
char domain_buf[32];
|
char domain_buf[32];
|
||||||
char from_buf[32];
|
char from_buf[32];
|
||||||
|
|
@ -997,6 +1028,9 @@ static bool amduatd_handle_get_fed_records(int fd,
|
||||||
return amduatd_http_send_text(fd, 500, "Internal Server Error",
|
return amduatd_http_send_text(fd, 500, "Internal Server Error",
|
||||||
"internal error\n", false);
|
"internal error\n", false);
|
||||||
}
|
}
|
||||||
|
if (!amduatd_fed_require_space(fd, fed_cfg, req)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (amduatd_query_param(req->path, "domain_id",
|
if (amduatd_query_param(req->path, "domain_id",
|
||||||
domain_buf, sizeof(domain_buf)) == NULL ||
|
domain_buf, sizeof(domain_buf)) == NULL ||
|
||||||
!amduatd_parse_u32_str(domain_buf, &domain_id)) {
|
!amduatd_parse_u32_str(domain_buf, &domain_id)) {
|
||||||
|
|
@ -1179,6 +1213,7 @@ fed_records_oom:
|
||||||
|
|
||||||
static bool amduatd_handle_get_fed_artifact(int fd,
|
static bool amduatd_handle_get_fed_artifact(int fd,
|
||||||
amduat_asl_store_t *store,
|
amduat_asl_store_t *store,
|
||||||
|
const amduatd_fed_cfg_t *fed_cfg,
|
||||||
const amduatd_http_req_t *req,
|
const amduatd_http_req_t *req,
|
||||||
const char *path) {
|
const char *path) {
|
||||||
char no_query[1024];
|
char no_query[1024];
|
||||||
|
|
@ -1191,6 +1226,9 @@ static bool amduatd_handle_get_fed_artifact(int fd,
|
||||||
return amduatd_http_send_text(fd, 500, "Internal Server Error",
|
return amduatd_http_send_text(fd, 500, "Internal Server Error",
|
||||||
"internal error\n", false);
|
"internal error\n", false);
|
||||||
}
|
}
|
||||||
|
if (!amduatd_fed_require_space(fd, fed_cfg, req)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
amduatd_path_without_query(path, no_query, sizeof(no_query));
|
amduatd_path_without_query(path, no_query, sizeof(no_query));
|
||||||
if (strncmp(no_query, "/v1/fed/artifacts/", 18) != 0) {
|
if (strncmp(no_query, "/v1/fed/artifacts/", 18) != 0) {
|
||||||
return amduatd_http_send_text(fd, 404, "Not Found", "not found\n", false);
|
return amduatd_http_send_text(fd, 404, "Not Found", "not found\n", false);
|
||||||
|
|
@ -1228,13 +1266,20 @@ static bool amduatd_handle_get_fed_artifact(int fd,
|
||||||
|
|
||||||
static bool amduatd_handle_get_fed_status(int fd,
|
static bool amduatd_handle_get_fed_status(int fd,
|
||||||
const amduat_fed_coord_t *coord,
|
const amduat_fed_coord_t *coord,
|
||||||
|
const amduatd_fed_cfg_t *fed_cfg,
|
||||||
const amduatd_http_req_t *req) {
|
const amduatd_http_req_t *req) {
|
||||||
amduat_fed_coord_status_t status;
|
amduat_fed_coord_status_t status;
|
||||||
char *ref_hex = NULL;
|
char *ref_hex = NULL;
|
||||||
char json[512];
|
char json[512];
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
(void)req;
|
if (!amduatd_fed_require_space(fd, fed_cfg, req)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (coord == NULL || fed_cfg == NULL || !fed_cfg->enabled) {
|
||||||
|
return amduatd_http_send_text(fd, 503, "Service Unavailable",
|
||||||
|
"federation disabled\n", false);
|
||||||
|
}
|
||||||
amduat_fed_coord_get_status(coord, &status);
|
amduat_fed_coord_get_status(coord, &status);
|
||||||
if (status.registry_ref.hash_id != 0 &&
|
if (status.registry_ref.hash_id != 0 &&
|
||||||
status.registry_ref.digest.data != NULL) {
|
status.registry_ref.digest.data != NULL) {
|
||||||
|
|
@ -3870,6 +3915,7 @@ static bool amduatd_handle_conn(int fd,
|
||||||
amduat_reference_t ui_ref,
|
amduat_reference_t ui_ref,
|
||||||
amduatd_concepts_t *concepts,
|
amduatd_concepts_t *concepts,
|
||||||
const amduatd_cfg_t *dcfg,
|
const amduatd_cfg_t *dcfg,
|
||||||
|
const amduatd_fed_cfg_t *fed_cfg,
|
||||||
const amduat_fed_coord_t *coord,
|
const amduat_fed_coord_t *coord,
|
||||||
const amduatd_allowlist_t *allowlist,
|
const amduatd_allowlist_t *allowlist,
|
||||||
amduatd_caps_t *caps,
|
amduatd_caps_t *caps,
|
||||||
|
|
@ -3971,12 +4017,12 @@ static bool amduatd_handle_conn(int fd,
|
||||||
}
|
}
|
||||||
if (strcmp(req.method, "GET") == 0 &&
|
if (strcmp(req.method, "GET") == 0 &&
|
||||||
strcmp(no_query, "/v1/fed/records") == 0) {
|
strcmp(no_query, "/v1/fed/records") == 0) {
|
||||||
ok = amduatd_handle_get_fed_records(fd, store, &req);
|
ok = amduatd_handle_get_fed_records(fd, store, fed_cfg, &req);
|
||||||
goto conn_cleanup;
|
goto conn_cleanup;
|
||||||
}
|
}
|
||||||
if (strcmp(req.method, "GET") == 0 &&
|
if (strcmp(req.method, "GET") == 0 &&
|
||||||
strcmp(no_query, "/v1/fed/status") == 0) {
|
strcmp(no_query, "/v1/fed/status") == 0) {
|
||||||
ok = amduatd_handle_get_fed_status(fd, coord, &req);
|
ok = amduatd_handle_get_fed_status(fd, coord, fed_cfg, &req);
|
||||||
goto conn_cleanup;
|
goto conn_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4042,7 +4088,7 @@ static bool amduatd_handle_conn(int fd,
|
||||||
}
|
}
|
||||||
if (strcmp(req.method, "GET") == 0 &&
|
if (strcmp(req.method, "GET") == 0 &&
|
||||||
strncmp(no_query, "/v1/fed/artifacts/", 18) == 0) {
|
strncmp(no_query, "/v1/fed/artifacts/", 18) == 0) {
|
||||||
ok = amduatd_handle_get_fed_artifact(fd, store, &req, req.path);
|
ok = amduatd_handle_get_fed_artifact(fd, store, fed_cfg, &req, req.path);
|
||||||
goto conn_cleanup;
|
goto conn_cleanup;
|
||||||
}
|
}
|
||||||
if (strcmp(req.method, "GET") == 0 &&
|
if (strcmp(req.method, "GET") == 0 &&
|
||||||
|
|
@ -4089,6 +4135,10 @@ static void amduatd_print_usage(FILE *stream) {
|
||||||
" [--space SPACE_ID] [--migrate-unscoped-edges]\n"
|
" [--space SPACE_ID] [--migrate-unscoped-edges]\n"
|
||||||
" [--edges-refresh-ms MS]\n"
|
" [--edges-refresh-ms MS]\n"
|
||||||
" [--store-backend fs|index]\n"
|
" [--store-backend fs|index]\n"
|
||||||
|
" [--fed-enable] [--fed-transport stub|unix]\n"
|
||||||
|
" [--fed-unix-sock PATH]\n"
|
||||||
|
" [--fed-domain-id ID] [--fed-registry-ref REF]\n"
|
||||||
|
" [--fed-require-space]\n"
|
||||||
" [--allow-uid UID] [--allow-user NAME]\n"
|
" [--allow-uid UID] [--allow-user NAME]\n"
|
||||||
" [--enable-cap-reads]\n"
|
" [--enable-cap-reads]\n"
|
||||||
" [--enable-derivation-index]\n"
|
" [--enable-derivation-index]\n"
|
||||||
|
|
@ -4116,14 +4166,17 @@ int main(int argc, char **argv) {
|
||||||
amduat_reference_t api_contract_ref;
|
amduat_reference_t api_contract_ref;
|
||||||
amduat_reference_t ui_ref;
|
amduat_reference_t ui_ref;
|
||||||
amduatd_concepts_t concepts;
|
amduatd_concepts_t concepts;
|
||||||
|
amduatd_fed_cfg_t fed_cfg;
|
||||||
amduat_fed_transport_stub_t fed_stub;
|
amduat_fed_transport_stub_t fed_stub;
|
||||||
amduat_fed_coord_cfg_t fed_cfg;
|
amduat_fed_transport_unix_t fed_unix;
|
||||||
|
amduat_fed_coord_cfg_t fed_coord_cfg;
|
||||||
amduat_fed_coord_t *fed_coord = NULL;
|
amduat_fed_coord_t *fed_coord = NULL;
|
||||||
amduatd_allowlist_t allowlist;
|
amduatd_allowlist_t allowlist;
|
||||||
int i;
|
int i;
|
||||||
int sfd = -1;
|
int sfd = -1;
|
||||||
uint64_t last_tick_ms = 0;
|
uint64_t last_tick_ms = 0;
|
||||||
uint64_t last_edges_refresh_ms = 0;
|
uint64_t last_edges_refresh_ms = 0;
|
||||||
|
const char *fed_err = NULL;
|
||||||
|
|
||||||
memset(&api_contract_ref, 0, sizeof(api_contract_ref));
|
memset(&api_contract_ref, 0, sizeof(api_contract_ref));
|
||||||
memset(&ui_ref, 0, sizeof(ui_ref));
|
memset(&ui_ref, 0, sizeof(ui_ref));
|
||||||
|
|
@ -4131,8 +4184,18 @@ int main(int argc, char **argv) {
|
||||||
memset(&allowlist, 0, sizeof(allowlist));
|
memset(&allowlist, 0, sizeof(allowlist));
|
||||||
memset(&dcfg, 0, sizeof(dcfg));
|
memset(&dcfg, 0, sizeof(dcfg));
|
||||||
memset(&caps, 0, sizeof(caps));
|
memset(&caps, 0, sizeof(caps));
|
||||||
|
amduatd_fed_cfg_init(&fed_cfg);
|
||||||
|
|
||||||
for (i = 1; i < argc; ++i) {
|
for (i = 1; i < argc; ++i) {
|
||||||
|
amduatd_fed_parse_result_t fed_rc;
|
||||||
|
fed_rc = amduatd_fed_cfg_parse_arg(&fed_cfg, argc, argv, &i, &fed_err);
|
||||||
|
if (fed_rc == AMDUATD_FED_PARSE_OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (fed_rc == AMDUATD_FED_PARSE_ERROR) {
|
||||||
|
fprintf(stderr, "error: %s\n", fed_err != NULL ? fed_err : "fed parse error");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
if (strcmp(argv[i], "--root") == 0) {
|
if (strcmp(argv[i], "--root") == 0) {
|
||||||
if (i + 1 >= argc) {
|
if (i + 1 >= argc) {
|
||||||
fprintf(stderr, "error: --root requires a path\n");
|
fprintf(stderr, "error: --root requires a path\n");
|
||||||
|
|
@ -4231,6 +4294,13 @@ int main(int argc, char **argv) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!amduatd_fed_requirements_check(store_backend, &fed_cfg, &fed_err)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"error: %s\n",
|
||||||
|
fed_err != NULL ? fed_err : "invalid federation config");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (!amduatd_store_init(&store, &cfg, &store_ctx, root, store_backend)) {
|
if (!amduatd_store_init(&store, &cfg, &store_ctx, root, store_backend)) {
|
||||||
fprintf(stderr, "error: failed to initialize store: %s\n", root);
|
fprintf(stderr, "error: failed to initialize store: %s\n", root);
|
||||||
return 8;
|
return 8;
|
||||||
|
|
@ -4268,14 +4338,53 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
char *registry_hex = NULL;
|
||||||
|
if (fed_cfg.registry_ref_set) {
|
||||||
|
if (!amduat_asl_ref_encode_hex(fed_cfg.registry_ref, ®istry_hex)) {
|
||||||
|
registry_hex = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
amduat_log(AMDUAT_LOG_INFO,
|
||||||
|
"federation enabled=%s transport=%s domain_id=%u registry_ref=%s require_space=%s",
|
||||||
|
fed_cfg.enabled ? "on" : "off",
|
||||||
|
amduatd_fed_transport_name(fed_cfg.transport_kind),
|
||||||
|
(unsigned int)fed_cfg.local_domain_id,
|
||||||
|
registry_hex != NULL ? registry_hex : "null",
|
||||||
|
fed_cfg.require_space ? "on" : "off");
|
||||||
|
free(registry_hex);
|
||||||
|
}
|
||||||
|
|
||||||
amduat_fed_transport_stub_init(&fed_stub);
|
amduat_fed_transport_stub_init(&fed_stub);
|
||||||
memset(&fed_cfg, 0, sizeof(fed_cfg));
|
memset(&fed_coord_cfg, 0, sizeof(fed_coord_cfg));
|
||||||
fed_cfg.local_domain_id = 0;
|
if (fed_cfg.enabled) {
|
||||||
fed_cfg.authoritative_store = &store;
|
fed_coord_cfg.local_domain_id = fed_cfg.local_domain_id;
|
||||||
fed_cfg.cache_store = NULL;
|
fed_coord_cfg.authoritative_store = &store;
|
||||||
fed_cfg.transport = amduat_fed_transport_stub_ops(&fed_stub);
|
fed_coord_cfg.cache_store = NULL;
|
||||||
if (amduat_fed_coord_open(&fed_cfg, &fed_coord) != AMDUAT_FED_COORD_OK) {
|
if (fed_cfg.registry_ref_set) {
|
||||||
fed_coord = NULL;
|
fed_coord_cfg.registry_ref = fed_cfg.registry_ref;
|
||||||
|
} else {
|
||||||
|
fed_coord_cfg.registry_ref = amduat_reference(0u, amduat_octets(NULL, 0u));
|
||||||
|
}
|
||||||
|
if (fed_cfg.transport_kind == AMDUATD_FED_TRANSPORT_UNIX) {
|
||||||
|
if (!amduat_fed_transport_unix_init(&fed_unix,
|
||||||
|
fed_cfg.unix_socket_path)) {
|
||||||
|
fprintf(stderr, "error: invalid --fed-unix-sock\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (dcfg.space.enabled) {
|
||||||
|
(void)amduat_fed_transport_unix_set_space(&fed_unix,
|
||||||
|
dcfg.space.space_id_buf);
|
||||||
|
}
|
||||||
|
fed_coord_cfg.transport = amduat_fed_transport_unix_ops(&fed_unix);
|
||||||
|
} else {
|
||||||
|
fed_coord_cfg.transport = amduat_fed_transport_stub_ops(&fed_stub);
|
||||||
|
}
|
||||||
|
if (amduat_fed_coord_open(&fed_coord_cfg, &fed_coord) !=
|
||||||
|
AMDUAT_FED_COORD_OK) {
|
||||||
|
fprintf(stderr, "error: failed to init federation coordinator\n");
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGINT, amduatd_on_signal);
|
signal(SIGINT, amduatd_on_signal);
|
||||||
|
|
@ -4378,6 +4487,7 @@ int main(int argc, char **argv) {
|
||||||
ui_ref,
|
ui_ref,
|
||||||
&concepts,
|
&concepts,
|
||||||
&dcfg,
|
&dcfg,
|
||||||
|
&fed_cfg,
|
||||||
fed_coord,
|
fed_coord,
|
||||||
&allowlist,
|
&allowlist,
|
||||||
&caps,
|
&caps,
|
||||||
|
|
|
||||||
236
src/amduatd_fed.c
Normal file
236
src/amduatd_fed.c
Normal file
|
|
@ -0,0 +1,236 @@
|
||||||
|
#include "amduatd_fed.h"
|
||||||
|
|
||||||
|
#include "amduat/asl/ref_text.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static bool amduatd_fed_parse_u32(const char *s, uint32_t *out) {
|
||||||
|
unsigned long val;
|
||||||
|
char *endp = NULL;
|
||||||
|
if (s == NULL || out == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
errno = 0;
|
||||||
|
val = strtoul(s, &endp, 10);
|
||||||
|
if (errno != 0 || endp == s || *endp != '\0' || val > UINT32_MAX) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out = (uint32_t)val;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void amduatd_fed_cfg_init(amduatd_fed_cfg_t *cfg) {
|
||||||
|
if (cfg == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(cfg, 0, sizeof(*cfg));
|
||||||
|
cfg->transport_kind = AMDUATD_FED_TRANSPORT_STUB;
|
||||||
|
cfg->registry_ref = amduat_reference(0u, amduat_octets(NULL, 0u));
|
||||||
|
}
|
||||||
|
|
||||||
|
void amduatd_fed_cfg_free(amduatd_fed_cfg_t *cfg) {
|
||||||
|
if (cfg == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cfg->registry_ref_set) {
|
||||||
|
amduat_reference_free(&cfg->registry_ref);
|
||||||
|
cfg->registry_ref_set = false;
|
||||||
|
}
|
||||||
|
amduatd_fed_cfg_init(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *amduatd_fed_transport_name(amduatd_fed_transport_kind_t kind) {
|
||||||
|
switch (kind) {
|
||||||
|
case AMDUATD_FED_TRANSPORT_STUB:
|
||||||
|
return "stub";
|
||||||
|
case AMDUATD_FED_TRANSPORT_UNIX:
|
||||||
|
return "unix";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
amduatd_fed_parse_result_t amduatd_fed_cfg_parse_arg(amduatd_fed_cfg_t *cfg,
|
||||||
|
int argc,
|
||||||
|
char **argv,
|
||||||
|
int *io_index,
|
||||||
|
const char **out_err) {
|
||||||
|
const char *arg = NULL;
|
||||||
|
const char *value = NULL;
|
||||||
|
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = NULL;
|
||||||
|
}
|
||||||
|
if (cfg == NULL || argv == NULL || io_index == NULL || argc <= 0) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "invalid fed config parse inputs";
|
||||||
|
}
|
||||||
|
return AMDUATD_FED_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
if (*io_index < 0 || *io_index >= argc) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "fed config parse index out of range";
|
||||||
|
}
|
||||||
|
return AMDUATD_FED_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
arg = argv[*io_index];
|
||||||
|
if (strcmp(arg, "--fed-enable") == 0) {
|
||||||
|
cfg->enabled = true;
|
||||||
|
return AMDUATD_FED_PARSE_OK;
|
||||||
|
}
|
||||||
|
if (strcmp(arg, "--fed-require-space") == 0) {
|
||||||
|
cfg->require_space = true;
|
||||||
|
return AMDUATD_FED_PARSE_OK;
|
||||||
|
}
|
||||||
|
if (strcmp(arg, "--fed-transport") == 0) {
|
||||||
|
if (*io_index + 1 >= argc) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "--fed-transport requires a value";
|
||||||
|
}
|
||||||
|
return AMDUATD_FED_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
value = argv[++(*io_index)];
|
||||||
|
if (strcmp(value, "stub") == 0) {
|
||||||
|
cfg->transport_kind = AMDUATD_FED_TRANSPORT_STUB;
|
||||||
|
return AMDUATD_FED_PARSE_OK;
|
||||||
|
}
|
||||||
|
if (strcmp(value, "unix") == 0) {
|
||||||
|
cfg->transport_kind = AMDUATD_FED_TRANSPORT_UNIX;
|
||||||
|
return AMDUATD_FED_PARSE_OK;
|
||||||
|
}
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "invalid --fed-transport";
|
||||||
|
}
|
||||||
|
return AMDUATD_FED_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
if (strcmp(arg, "--fed-unix-sock") == 0) {
|
||||||
|
size_t len;
|
||||||
|
if (*io_index + 1 >= argc) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "--fed-unix-sock requires a path";
|
||||||
|
}
|
||||||
|
return AMDUATD_FED_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
value = argv[++(*io_index)];
|
||||||
|
len = strlen(value);
|
||||||
|
if (len == 0 || len >= sizeof(cfg->unix_socket_path)) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "invalid --fed-unix-sock";
|
||||||
|
}
|
||||||
|
return AMDUATD_FED_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
memset(cfg->unix_socket_path, 0, sizeof(cfg->unix_socket_path));
|
||||||
|
memcpy(cfg->unix_socket_path, value, len);
|
||||||
|
cfg->unix_socket_set = true;
|
||||||
|
return AMDUATD_FED_PARSE_OK;
|
||||||
|
}
|
||||||
|
if (strcmp(arg, "--fed-domain-id") == 0) {
|
||||||
|
uint32_t domain_id = 0;
|
||||||
|
if (*io_index + 1 >= argc) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "--fed-domain-id requires a value";
|
||||||
|
}
|
||||||
|
return AMDUATD_FED_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
value = argv[++(*io_index)];
|
||||||
|
if (!amduatd_fed_parse_u32(value, &domain_id)) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "invalid --fed-domain-id";
|
||||||
|
}
|
||||||
|
return AMDUATD_FED_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
cfg->local_domain_id = domain_id;
|
||||||
|
return AMDUATD_FED_PARSE_OK;
|
||||||
|
}
|
||||||
|
if (strcmp(arg, "--fed-registry-ref") == 0) {
|
||||||
|
amduat_reference_t ref;
|
||||||
|
if (*io_index + 1 >= argc) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "--fed-registry-ref requires a value";
|
||||||
|
}
|
||||||
|
return AMDUATD_FED_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
value = argv[++(*io_index)];
|
||||||
|
memset(&ref, 0, sizeof(ref));
|
||||||
|
if (!amduat_asl_ref_decode_hex(value, &ref)) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "invalid --fed-registry-ref";
|
||||||
|
}
|
||||||
|
return AMDUATD_FED_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
if (cfg->registry_ref_set) {
|
||||||
|
amduat_reference_free(&cfg->registry_ref);
|
||||||
|
}
|
||||||
|
cfg->registry_ref = ref;
|
||||||
|
cfg->registry_ref_set = true;
|
||||||
|
return AMDUATD_FED_PARSE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AMDUATD_FED_PARSE_NOT_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduatd_fed_requirements_check(amduatd_store_backend_t backend,
|
||||||
|
const amduatd_fed_cfg_t *cfg,
|
||||||
|
const char **out_err) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = NULL;
|
||||||
|
}
|
||||||
|
if (cfg == NULL) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "missing fed config";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!cfg->enabled) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (backend != AMDUATD_STORE_BACKEND_INDEX) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "federation requires --store-backend index";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cfg->transport_kind == AMDUATD_FED_TRANSPORT_UNIX &&
|
||||||
|
!cfg->unix_socket_set) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "unix transport requires --fed-unix-sock";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool amduatd_fed_scope_names(const amduatd_fed_cfg_t *cfg,
|
||||||
|
const amduatd_space_t *space,
|
||||||
|
const char *name,
|
||||||
|
amduat_octets_t *out_scoped,
|
||||||
|
const char **out_err) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = NULL;
|
||||||
|
}
|
||||||
|
if (out_scoped != NULL) {
|
||||||
|
*out_scoped = amduat_octets(NULL, 0u);
|
||||||
|
}
|
||||||
|
if (cfg == NULL || name == NULL || out_scoped == NULL) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "invalid fed scope inputs";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cfg->require_space && (space == NULL || !space->enabled)) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "missing X-Amduat-Space";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!amduatd_space_scope_name(space, name, out_scoped)) {
|
||||||
|
if (out_err != NULL) {
|
||||||
|
*out_err = "failed to scope name";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
65
src/amduatd_fed.h
Normal file
65
src/amduatd_fed.h
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
#ifndef AMDUATD_FED_H
|
||||||
|
#define AMDUATD_FED_H
|
||||||
|
|
||||||
|
#include "amduatd_space.h"
|
||||||
|
#include "amduatd_store.h"
|
||||||
|
#include "federation/transport_unix.h"
|
||||||
|
|
||||||
|
#include "amduat/asl/core.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
AMDUATD_FED_TRANSPORT_STUB = 0,
|
||||||
|
AMDUATD_FED_TRANSPORT_UNIX = 1
|
||||||
|
} amduatd_fed_transport_kind_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool enabled;
|
||||||
|
bool require_space;
|
||||||
|
amduatd_fed_transport_kind_t transport_kind;
|
||||||
|
uint32_t local_domain_id;
|
||||||
|
bool registry_ref_set;
|
||||||
|
amduat_reference_t registry_ref;
|
||||||
|
bool unix_socket_set;
|
||||||
|
char unix_socket_path[AMDUAT_FED_TRANSPORT_UNIX_PATH_MAX];
|
||||||
|
} amduatd_fed_cfg_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
AMDUATD_FED_PARSE_OK = 0,
|
||||||
|
AMDUATD_FED_PARSE_NOT_HANDLED = 1,
|
||||||
|
AMDUATD_FED_PARSE_ERROR = 2
|
||||||
|
} amduatd_fed_parse_result_t;
|
||||||
|
|
||||||
|
void amduatd_fed_cfg_init(amduatd_fed_cfg_t *cfg);
|
||||||
|
|
||||||
|
void amduatd_fed_cfg_free(amduatd_fed_cfg_t *cfg);
|
||||||
|
|
||||||
|
const char *amduatd_fed_transport_name(amduatd_fed_transport_kind_t kind);
|
||||||
|
|
||||||
|
amduatd_fed_parse_result_t amduatd_fed_cfg_parse_arg(amduatd_fed_cfg_t *cfg,
|
||||||
|
int argc,
|
||||||
|
char **argv,
|
||||||
|
int *io_index,
|
||||||
|
const char **out_err);
|
||||||
|
|
||||||
|
bool amduatd_fed_requirements_check(amduatd_store_backend_t backend,
|
||||||
|
const amduatd_fed_cfg_t *cfg,
|
||||||
|
const char **out_err);
|
||||||
|
|
||||||
|
bool amduatd_fed_scope_names(const amduatd_fed_cfg_t *cfg,
|
||||||
|
const amduatd_space_t *space,
|
||||||
|
const char *name,
|
||||||
|
amduat_octets_t *out_scoped,
|
||||||
|
const char **out_err);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* AMDUATD_FED_H */
|
||||||
121
tests/test_amduatd_fed_cfg.c
Normal file
121
tests/test_amduatd_fed_cfg.c
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
#include "amduatd_fed.h"
|
||||||
|
|
||||||
|
#include "amduat/asl/ref_text.h"
|
||||||
|
#include "amduat/hash/asl1.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static int failures = 0;
|
||||||
|
|
||||||
|
static void expect(bool cond, const char *msg) {
|
||||||
|
if (!cond) {
|
||||||
|
fprintf(stderr, "FAIL: %s\n", msg);
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
amduatd_fed_cfg_t cfg;
|
||||||
|
amduatd_space_t space;
|
||||||
|
amduat_octets_t scoped = amduat_octets(NULL, 0u);
|
||||||
|
uint8_t digest_bytes[32];
|
||||||
|
amduat_octets_t digest;
|
||||||
|
amduat_reference_t ref;
|
||||||
|
char *ref_hex = NULL;
|
||||||
|
const char *err = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(digest_bytes, 0x2a, sizeof(digest_bytes));
|
||||||
|
if (!amduat_octets_clone(amduat_octets(digest_bytes, sizeof(digest_bytes)),
|
||||||
|
&digest)) {
|
||||||
|
fprintf(stderr, "FAIL: digest clone\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ref = amduat_reference(AMDUAT_HASH_ASL1_ID_SHA256, digest);
|
||||||
|
if (!amduat_asl_ref_encode_hex(ref, &ref_hex)) {
|
||||||
|
fprintf(stderr, "FAIL: ref encode\n");
|
||||||
|
amduat_reference_free(&ref);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
amduatd_fed_cfg_init(&cfg);
|
||||||
|
expect(!cfg.enabled, "default disabled");
|
||||||
|
expect(cfg.transport_kind == AMDUATD_FED_TRANSPORT_STUB, "default transport");
|
||||||
|
expect(!cfg.require_space, "default require_space");
|
||||||
|
|
||||||
|
{
|
||||||
|
char *argv[] = {
|
||||||
|
"amduatd",
|
||||||
|
"--fed-enable",
|
||||||
|
"--fed-transport",
|
||||||
|
"unix",
|
||||||
|
"--fed-unix-sock",
|
||||||
|
"amduatd.sock",
|
||||||
|
"--fed-domain-id",
|
||||||
|
"42",
|
||||||
|
"--fed-registry-ref",
|
||||||
|
ref_hex,
|
||||||
|
"--fed-require-space",
|
||||||
|
};
|
||||||
|
int argc = (int)(sizeof(argv) / sizeof(argv[0]));
|
||||||
|
for (i = 1; i < argc; ++i) {
|
||||||
|
amduatd_fed_parse_result_t rc;
|
||||||
|
rc = amduatd_fed_cfg_parse_arg(&cfg, argc, argv, &i, &err);
|
||||||
|
expect(rc == AMDUATD_FED_PARSE_OK, "fed parse ok");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(cfg.enabled, "parsed enabled");
|
||||||
|
expect(cfg.transport_kind == AMDUATD_FED_TRANSPORT_UNIX,
|
||||||
|
"parsed transport");
|
||||||
|
expect(cfg.unix_socket_set, "parsed unix socket");
|
||||||
|
expect(cfg.local_domain_id == 42u, "parsed domain id");
|
||||||
|
expect(cfg.registry_ref_set, "parsed registry ref");
|
||||||
|
expect(cfg.require_space, "parsed require space");
|
||||||
|
|
||||||
|
expect(!amduatd_fed_requirements_check(AMDUATD_STORE_BACKEND_FS,
|
||||||
|
&cfg,
|
||||||
|
&err),
|
||||||
|
"requirements reject fs backend");
|
||||||
|
expect(amduatd_fed_requirements_check(AMDUATD_STORE_BACKEND_INDEX,
|
||||||
|
&cfg,
|
||||||
|
&err),
|
||||||
|
"requirements accept index backend");
|
||||||
|
|
||||||
|
if (!amduatd_space_init(&space, NULL, false)) {
|
||||||
|
fprintf(stderr, "FAIL: space init\n");
|
||||||
|
amduatd_fed_cfg_free(&cfg);
|
||||||
|
amduat_reference_free(&ref);
|
||||||
|
free(ref_hex);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
expect(!amduatd_fed_scope_names(&cfg, &space, "fed", &scoped, &err),
|
||||||
|
"scope requires space");
|
||||||
|
amduat_octets_free(&scoped);
|
||||||
|
|
||||||
|
if (!amduatd_space_init(&space, "alpha", false)) {
|
||||||
|
fprintf(stderr, "FAIL: space init alpha\n");
|
||||||
|
amduatd_fed_cfg_free(&cfg);
|
||||||
|
amduat_reference_free(&ref);
|
||||||
|
free(ref_hex);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
expect(amduatd_fed_scope_names(&cfg, &space, "fed", &scoped, &err),
|
||||||
|
"scope with space");
|
||||||
|
expect(scoped.data != NULL &&
|
||||||
|
scoped.len == strlen("space/alpha/fed") &&
|
||||||
|
memcmp(scoped.data,
|
||||||
|
"space/alpha/fed",
|
||||||
|
scoped.len) == 0,
|
||||||
|
"scoped name");
|
||||||
|
amduat_octets_free(&scoped);
|
||||||
|
|
||||||
|
amduatd_fed_cfg_free(&cfg);
|
||||||
|
amduat_reference_free(&ref);
|
||||||
|
free(ref_hex);
|
||||||
|
return failures == 0 ? 0 : 1;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue