BOC v1.0: RS256 auth, Ledger integration, Prometheus metrics, CI/CD, backup

This commit is contained in:
Bernt
2026-07-28 23:08:32 +00:00
parent 0b4f160af1
commit af874040ca
11541 changed files with 1654104 additions and 1103 deletions
+25
View File
@@ -0,0 +1,25 @@
CC = gcc
CFLAGS = -Wall -Wextra -O2 -fPIC -D_GNU_SOURCE
LDFLAGS = -shared -lpthread -lrt
TARGET = libcrt.so
OBJS = shm.o ringbuf.o cache.o
.PHONY: all clean test
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
%.o: %.c %.h
$(CC) $(CFLAGS) -c $< -o $@
test: test_crt
./test_crt
test_crt: test_crt.c $(TARGET)
$(CC) -o $@ $< -L. -lcrt -Wl,-rpath,.
clean:
rm -f $(OBJS) $(TARGET) test_crt
+220
View File
@@ -0,0 +1,220 @@
#include "cache.h"
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
struct crt_cache {
crt_cache_entry_t** buckets;
size_t bucket_count;
size_t max_entries;
size_t current_entries;
time_t default_ttl;
pthread_rwlock_t lock;
};
static size_t hash_key(const char* key) {
size_t hash = 5381;
int c;
while ((c = *key++)) {
hash = ((hash << 5) + hash) + c;
}
return hash;
}
crt_cache_t* crt_cache_create(size_t max_entries, time_t default_ttl_sec) {
crt_cache_t* cache = calloc(1, sizeof(crt_cache_t));
if (!cache) return NULL;
cache->bucket_count = 1024;
cache->buckets = calloc(cache->bucket_count, sizeof(crt_cache_entry_t*));
if (!cache->buckets) {
free(cache);
return NULL;
}
cache->max_entries = max_entries;
cache->default_ttl = default_ttl_sec;
cache->current_entries = 0;
pthread_rwlock_init(&cache->lock, NULL);
return cache;
}
void crt_cache_destroy(crt_cache_t* cache) {
if (!cache) return;
crt_cache_clear(cache);
free(cache->buckets);
pthread_rwlock_destroy(&cache->lock);
free(cache);
}
bool crt_cache_set(crt_cache_t* cache, const char* key, const void* data, size_t len) {
return crt_cache_set_ttl(cache, key, data, len, cache->default_ttl);
}
bool crt_cache_set_ttl(crt_cache_t* cache, const char* key, const void* data, size_t len, time_t ttl_sec) {
if (!cache || !key || !data || len == 0) return false;
pthread_rwlock_wrlock(&cache->lock);
if (cache->current_entries >= cache->max_entries) {
crt_cache_evict_expired(cache);
}
size_t idx = hash_key(key) % cache->bucket_count;
crt_cache_entry_t* entry = cache->buckets[idx];
while (entry) {
if (strcmp(entry->key, key) == 0) {
free(entry->data);
entry->data = malloc(len);
if (!entry->data) {
pthread_rwlock_unlock(&cache->lock);
return false;
}
memcpy(entry->data, data, len);
entry->len = len;
entry->expires_at = time(NULL) + ttl_sec;
pthread_rwlock_unlock(&cache->lock);
return true;
}
entry = entry->next;
}
entry = malloc(sizeof(crt_cache_entry_t));
if (!entry) {
pthread_rwlock_unlock(&cache->lock);
return false;
}
strncpy(entry->key, key, sizeof(entry->key) - 1);
entry->data = malloc(len);
if (!entry->data) {
free(entry);
pthread_rwlock_unlock(&cache->lock);
return false;
}
memcpy(entry->data, data, len);
entry->len = len;
entry->expires_at = time(NULL) + ttl_sec;
entry->next = cache->buckets[idx];
cache->buckets[idx] = entry;
cache->current_entries++;
pthread_rwlock_unlock(&cache->lock);
return true;
}
bool crt_cache_get(crt_cache_t* cache, const char* key, void* out, size_t* len) {
if (!cache || !key || !out || !len) return false;
pthread_rwlock_rdlock(&cache->lock);
size_t idx = hash_key(key) % cache->bucket_count;
crt_cache_entry_t* entry = cache->buckets[idx];
time_t now = time(NULL);
while (entry) {
if (strcmp(entry->key, key) == 0) {
if (entry->expires_at < now) {
pthread_rwlock_unlock(&cache->lock);
crt_cache_delete(cache, key);
return false;
}
memcpy(out, entry->data, entry->len);
*len = entry->len;
pthread_rwlock_unlock(&cache->lock);
return true;
}
entry = entry->next;
}
pthread_rwlock_unlock(&cache->lock);
return false;
}
bool crt_cache_delete(crt_cache_t* cache, const char* key) {
if (!cache || !key) return false;
pthread_rwlock_wrlock(&cache->lock);
size_t idx = hash_key(key) % cache->bucket_count;
crt_cache_entry_t* entry = cache->buckets[idx];
crt_cache_entry_t* prev = NULL;
while (entry) {
if (strcmp(entry->key, key) == 0) {
if (prev) {
prev->next = entry->next;
} else {
cache->buckets[idx] = entry->next;
}
free(entry->data);
free(entry);
cache->current_entries--;
pthread_rwlock_unlock(&cache->lock);
return true;
}
prev = entry;
entry = entry->next;
}
pthread_rwlock_unlock(&cache->lock);
return false;
}
void crt_cache_clear(crt_cache_t* cache) {
if (!cache) return;
pthread_rwlock_wrlock(&cache->lock);
for (size_t i = 0; i < cache->bucket_count; i++) {
crt_cache_entry_t* entry = cache->buckets[i];
while (entry) {
crt_cache_entry_t* next = entry->next;
free(entry->data);
free(entry);
entry = next;
}
cache->buckets[i] = NULL;
}
cache->current_entries = 0;
pthread_rwlock_unlock(&cache->lock);
}
size_t crt_cache_size(crt_cache_t* cache) {
if (!cache) return 0;
pthread_rwlock_rdlock(&cache->lock);
size_t size = cache->current_entries;
pthread_rwlock_unlock(&cache->lock);
return size;
}
void crt_cache_evict_expired(crt_cache_t* cache) {
if (!cache) return;
time_t now = time(NULL);
for (size_t i = 0; i < cache->bucket_count; i++) {
crt_cache_entry_t* entry = cache->buckets[i];
crt_cache_entry_t* prev = NULL;
while (entry) {
crt_cache_entry_t* next = entry->next;
if (entry->expires_at < now) {
if (prev) {
prev->next = next;
} else {
cache->buckets[i] = next;
}
free(entry->data);
free(entry);
cache->current_entries--;
} else {
prev = entry;
}
entry = next;
}
}
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef CRT_CACHE_H
#define CRT_CACHE_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct crt_cache crt_cache_t;
typedef struct crt_cache_entry {
char key[256];
uint8_t* data;
size_t len;
time_t expires_at;
struct crt_cache_entry* next;
} crt_cache_entry_t;
crt_cache_t* crt_cache_create(size_t max_entries, time_t default_ttl_sec);
void crt_cache_destroy(crt_cache_t* cache);
bool crt_cache_set(crt_cache_t* cache, const char* key, const void* data, size_t len);
bool crt_cache_set_ttl(crt_cache_t* cache, const char* key, const void* data, size_t len, time_t ttl_sec);
bool crt_cache_get(crt_cache_t* cache, const char* key, void* out, size_t* len);
bool crt_cache_delete(crt_cache_t* cache, const char* key);
void crt_cache_clear(crt_cache_t* cache);
size_t crt_cache_size(crt_cache_t* cache);
void crt_cache_evict_expired(crt_cache_t* cache);
#ifdef __cplusplus
}
#endif
#endif
+149
View File
@@ -0,0 +1,149 @@
#include "ringbuf.h"
#include <stdlib.h>
#include <string.h>
#include <stdatomic.h>
struct crt_ringbuf {
uint8_t* buffer;
size_t capacity;
size_t head;
size_t tail;
atomic_size_t count;
};
crt_ringbuf_t* crt_ringbuf_create(size_t capacity) {
crt_ringbuf_t* rb = calloc(1, sizeof(crt_ringbuf_t));
if (!rb) return NULL;
rb->buffer = malloc(capacity);
if (!rb->buffer) {
free(rb);
return NULL;
}
rb->capacity = capacity;
rb->head = 0;
rb->tail = 0;
atomic_init(&rb->count, 0);
return rb;
}
void crt_ringbuf_destroy(crt_ringbuf_t* rb) {
if (!rb) return;
free(rb->buffer);
free(rb);
}
bool crt_ringbuf_push(crt_ringbuf_t* rb, const void* data, size_t len) {
if (!rb || !data || len == 0) return false;
if (len + sizeof(size_t) > rb->capacity) return false;
size_t current = atomic_load(&rb->count);
if (current >= rb->capacity - len - sizeof(size_t)) return false;
size_t head = rb->head;
size_t needed = len + sizeof(size_t);
if (head + needed <= rb->capacity) {
memcpy(rb->buffer + head, &len, sizeof(size_t));
memcpy(rb->buffer + head + sizeof(size_t), data, len);
rb->head = (head + needed) % rb->capacity;
} else {
size_t first_part = rb->capacity - head;
if (first_part >= sizeof(size_t)) {
memcpy(rb->buffer + head, &len, sizeof(size_t));
memcpy(rb->buffer + head + sizeof(size_t), data, first_part - sizeof(size_t));
memcpy(rb->buffer, (uint8_t*)data + first_part - sizeof(size_t), len - (first_part - sizeof(size_t)));
} else {
memcpy(rb->buffer + head, &len, first_part);
memcpy(rb->buffer, (uint8_t*)&len + first_part, sizeof(size_t) - first_part);
memcpy(rb->buffer + sizeof(size_t) - first_part, data, len);
}
rb->head = needed - first_part;
}
atomic_fetch_add(&rb->count, needed);
return true;
}
bool crt_ringbuf_pop(crt_ringbuf_t* rb, void* out, size_t* len) {
if (!rb || !out || !len) return false;
if (atomic_load(&rb->count) == 0) return false;
size_t tail = rb->tail;
size_t stored_len;
if (tail + sizeof(size_t) <= rb->capacity) {
memcpy(&stored_len, rb->buffer + tail, sizeof(size_t));
} else {
size_t first_part = rb->capacity - tail;
memcpy(&stored_len, rb->buffer + tail, first_part);
memcpy((uint8_t*)&stored_len + first_part, rb->buffer, sizeof(size_t) - first_part);
}
size_t total_size = stored_len + sizeof(size_t);
if (tail + total_size <= rb->capacity) {
memcpy(out, rb->buffer + tail + sizeof(size_t), stored_len);
} else {
size_t first_part = rb->capacity - tail - sizeof(size_t);
memcpy(out, rb->buffer + tail + sizeof(size_t), first_part);
memcpy((uint8_t*)out + first_part, rb->buffer, stored_len - first_part);
}
rb->tail = (tail + total_size) % rb->capacity;
atomic_fetch_sub(&rb->count, total_size);
*len = stored_len;
return true;
}
bool crt_ringbuf_peek(crt_ringbuf_t* rb, void* out, size_t* len) {
if (!rb || !out || !len) return false;
if (atomic_load(&rb->count) == 0) return false;
size_t tail = rb->tail;
size_t stored_len;
if (tail + sizeof(size_t) <= rb->capacity) {
memcpy(&stored_len, rb->buffer + tail, sizeof(size_t));
} else {
size_t first_part = rb->capacity - tail;
memcpy(&stored_len, rb->buffer + tail, first_part);
memcpy((uint8_t*)&stored_len + first_part, rb->buffer, sizeof(size_t) - first_part);
}
size_t total_size = stored_len + sizeof(size_t);
if (tail + total_size <= rb->capacity) {
memcpy(out, rb->buffer + tail + sizeof(size_t), stored_len);
} else {
size_t first_part = rb->capacity - tail - sizeof(size_t);
memcpy(out, rb->buffer + tail + sizeof(size_t), first_part);
memcpy((uint8_t*)out + first_part, rb->buffer, stored_len - first_part);
}
*len = stored_len;
return true;
}
size_t crt_ringbuf_count(crt_ringbuf_t* rb) {
return rb ? atomic_load(&rb->count) : 0;
}
size_t crt_ringbuf_capacity(crt_ringbuf_t* rb) {
return rb ? rb->capacity : 0;
}
bool crt_ringbuf_empty(crt_ringbuf_t* rb) {
return rb ? atomic_load(&rb->count) == 0 : true;
}
bool crt_ringbuf_full(crt_ringbuf_t* rb) {
return rb ? atomic_load(&rb->count) >= rb->capacity : true;
}
void crt_ringbuf_clear(crt_ringbuf_t* rb) {
if (!rb) return;
rb->head = 0;
rb->tail = 0;
atomic_store(&rb->count, 0);
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef CRT_RINGBUF_H
#define CRT_RINGBUF_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct crt_ringbuf crt_ringbuf_t;
crt_ringbuf_t* crt_ringbuf_create(size_t capacity);
void crt_ringbuf_destroy(crt_ringbuf_t* rb);
bool crt_ringbuf_push(crt_ringbuf_t* rb, const void* data, size_t len);
bool crt_ringbuf_pop(crt_ringbuf_t* rb, void* out, size_t* len);
bool crt_ringbuf_peek(crt_ringbuf_t* rb, void* out, size_t* len);
size_t crt_ringbuf_count(crt_ringbuf_t* rb);
size_t crt_ringbuf_capacity(crt_ringbuf_t* rb);
bool crt_ringbuf_empty(crt_ringbuf_t* rb);
bool crt_ringbuf_full(crt_ringbuf_t* rb);
void crt_ringbuf_clear(crt_ringbuf_t* rb);
#ifdef __cplusplus
}
#endif
#endif
+109
View File
@@ -0,0 +1,109 @@
#include "shm.h"
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
struct crt_shm {
int fd;
void* ptr;
size_t size;
char name[256];
};
crt_shm_t* crt_shm_create(const char* name, size_t size) {
crt_shm_t* shm = calloc(1, sizeof(crt_shm_t));
if (!shm) return NULL;
strncpy(shm->name, name, sizeof(shm->name) - 1);
shm->size = size;
shm->fd = shm_open(name, O_CREAT | O_RDWR, 0666);
if (shm->fd < 0) {
free(shm);
return NULL;
}
if (ftruncate(shm->fd, size) < 0) {
close(shm->fd);
shm_unlink(name);
free(shm);
return NULL;
}
shm->ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm->fd, 0);
if (shm->ptr == MAP_FAILED) {
close(shm->fd);
shm_unlink(name);
free(shm);
return NULL;
}
memset(shm->ptr, 0, size);
return shm;
}
crt_shm_t* crt_shm_open(const char* name) {
crt_shm_t* shm = calloc(1, sizeof(crt_shm_t));
if (!shm) return NULL;
strncpy(shm->name, name, sizeof(shm->name) - 1);
shm->fd = shm_open(name, O_RDWR, 0666);
if (shm->fd < 0) {
free(shm);
return NULL;
}
struct stat st;
if (fstat(shm->fd, &st) < 0) {
close(shm->fd);
free(shm);
return NULL;
}
shm->size = st.st_size;
shm->ptr = mmap(NULL, shm->size, PROT_READ | PROT_WRITE, MAP_SHARED, shm->fd, 0);
if (shm->ptr == MAP_FAILED) {
close(shm->fd);
free(shm);
return NULL;
}
return shm;
}
void crt_shm_close(crt_shm_t* shm) {
if (!shm) return;
if (shm->ptr && shm->ptr != MAP_FAILED) {
munmap(shm->ptr, shm->size);
}
if (shm->fd >= 0) {
close(shm->fd);
}
free(shm);
}
void* crt_shm_ptr(crt_shm_t* shm) {
return shm ? shm->ptr : NULL;
}
size_t crt_shm_size(crt_shm_t* shm) {
return shm ? shm->size : 0;
}
int crt_shm_resize(crt_shm_t* shm, size_t new_size) {
if (!shm || !shm->ptr) return -1;
if (munmap(shm->ptr, shm->size) < 0) return -1;
if (ftruncate(shm->fd, new_size) < 0) return -1;
shm->ptr = mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm->fd, 0);
if (shm->ptr == MAP_FAILED) return -1;
shm->size = new_size;
return 0;
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef CRT_SHM_H
#define CRT_SHM_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct crt_shm crt_shm_t;
crt_shm_t* crt_shm_create(const char* name, size_t size);
crt_shm_t* crt_shm_open(const char* name);
void crt_shm_close(crt_shm_t* shm);
void* crt_shm_ptr(crt_shm_t* shm);
size_t crt_shm_size(crt_shm_t* shm);
int crt_shm_resize(crt_shm_t* shm, size_t new_size);
#ifdef __cplusplus
}
#endif
#endif