diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 34543817..a977ef4f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,7 @@ set(od_src od_lex.c od_scheme.c od_config.c + od_id.c od_instance.c od_server_pool.c od_client_pool.c diff --git a/src/od_auth.c b/src/od_auth.c index 731338f3..9b413da6 100644 --- a/src/od_auth.c +++ b/src/od_auth.c @@ -26,6 +26,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_msg.h" #include "od_system.h" #include "od_instance.h" diff --git a/src/od_backend.c b/src/od_backend.c index b3302150..4351143a 100644 --- a/src/od_backend.c +++ b/src/od_backend.c @@ -26,6 +26,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_msg.h" #include "od_system.h" #include "od_instance.h" diff --git a/src/od_cancel.c b/src/od_cancel.c index 9338d7a9..37288409 100644 --- a/src/od_cancel.c +++ b/src/od_cancel.c @@ -26,6 +26,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_msg.h" #include "od_system.h" #include "od_instance.h" diff --git a/src/od_client_pool.c b/src/od_client_pool.c index e632ccf3..1a985fa7 100644 --- a/src/od_client_pool.c +++ b/src/od_client_pool.c @@ -24,6 +24,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_system.h" #include "od_server.h" #include "od_server_pool.h" diff --git a/src/od_frontend.c b/src/od_frontend.c index a633b655..729ccf0d 100644 --- a/src/od_frontend.c +++ b/src/od_frontend.c @@ -26,6 +26,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_msg.h" #include "od_system.h" #include "od_instance.h" diff --git a/src/od_id.c b/src/od_id.c new file mode 100644 index 00000000..e8ea761f --- /dev/null +++ b/src/od_id.c @@ -0,0 +1,130 @@ + +/* + * ODISSEY. + * + * PostgreSQL connection pooler and request router. +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "od_macro.h" +#include "od_pid.h" +#include "od_syslog.h" +#include "od_log.h" +#include "od_id.h" + +void od_idmgr_init(od_idmgr_t *mgr) +{ + memset(mgr->seed, 0, sizeof(mgr->seed)); + mgr->seq = 0; +} + +int od_idmgr_seed(od_idmgr_t *mgr, od_log_t *log) +{ + mgr->uid = getuid(); + mgr->pid = getpid(); + + struct timeval tv; + gettimeofday(&tv, 0); + srand((mgr->pid << 16) ^ mgr->uid ^ tv.tv_sec ^ tv.tv_usec); + int i = 0; + for (; i < 8; i++) + mgr->seed[i] = (rand() >> 7) & 0xFF; + int fd; + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) + fd = open("/dev/random", O_RDONLY); + if (fd == -1) { + od_error(log, "id_manager", "failed to open /dev/{u}random"); + return -1; + } + char seed[8]; + int seed_read = 0; + while (seed_read <= 8) { + int rc; + rc = read(fd, seed, sizeof(seed)); + if (rc == -1) { + if (errno == EAGAIN || errno == EINTR) + continue; + close(fd); + return -1; + } + seed_read += rc; + } + for (i = 0; i < 8; i++) + mgr->seed[i] ^= seed[i]; + close(fd); + return 0; +} + +static const uint8_t codetable[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx"; +static const size_t codetable_size = sizeof(codetable); +static const size_t codetable_single_divisor = sizeof(codetable) * 1; +static const size_t codetable_double_divisor = sizeof(codetable) * 2; +static const size_t codetable_triple_divisor = sizeof(codetable) * 3; + +void od_idmgr_generate(od_idmgr_t *mgr, od_id_t *id) +{ + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + time_t current_time = t.tv_sec; + + uint8_t second; + second = current_time % 60; + current_time /= 60; + + uint8_t minute; + minute = current_time % 60; + current_time /= 60; + + uint8_t hour; + hour = current_time % 24; + current_time /= 60; + + uint8_t day; + day = current_time % 30; + current_time /= 60; + + uint8_t month; + month = current_time % 12; + current_time /= 60; + + uint64_t seq; + seq = ++mgr->seq; + seq ^= t.tv_nsec; + + uint8_t *seed = &id->id[0]; + seed[0] = mgr->seed[0] ^ codetable[second]; + seed[1] = mgr->seed[1] ^ codetable[minute]; + seed[2] = mgr->seed[2] ^ codetable[(hour + day + month) % codetable_size]; + seed[3] = mgr->seed[3] ^ codetable[(seq) % codetable_size]; + seed[4] = mgr->seed[4] ^ codetable[(seq / codetable_single_divisor) % codetable_size]; + seed[5] = mgr->seed[5] ^ codetable[(seq / codetable_double_divisor) % codetable_size]; + seed[6] = mgr->seed[6] ^ codetable[(seq / codetable_triple_divisor) % codetable_size]; + seed[7] = mgr->seed[7] ^ codetable[(uintptr_t)id % codetable_size]; + seed[8] = mgr->seed[8] ^ codetable[(mgr->pid + mgr->uid) % codetable_size]; + memcpy(mgr->seed, seed, 8); +} diff --git a/src/od_id.h b/src/od_id.h new file mode 100644 index 00000000..4a26b70c --- /dev/null +++ b/src/od_id.h @@ -0,0 +1,30 @@ +#ifndef OD_ID_H +#define OD_ID_H + +/* + * ODISSEY. + * + * PostgreSQL connection pooler and request router. +*/ + +typedef struct od_id od_id_t; +typedef struct od_idmgr od_idmgr_t; + +struct od_id +{ + uint8_t id[8]; +}; + +struct od_idmgr +{ + uint64_t seq; + uint8_t seed[8]; + pid_t pid; + uid_t uid; +}; + +void od_idmgr_init(od_idmgr_t*); +int od_idmgr_seed(od_idmgr_t*, od_log_t*); +void od_idmgr_generate(od_idmgr_t*, od_id_t*); + +#endif /* OD_ID_H */ diff --git a/src/od_instance.c b/src/od_instance.c index 8e3256fa..610b8499 100644 --- a/src/od_instance.c +++ b/src/od_instance.c @@ -26,6 +26,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_msg.h" #include "od_system.h" #include "od_instance.h" @@ -53,6 +54,7 @@ void od_instance_init(od_instance_t *instance) od_log_init(&instance->log, &instance->pid, &instance->syslog); od_scheme_init(&instance->scheme); od_config_init(&instance->config, &instance->log, &instance->scheme); + od_idmgr_init(&instance->id_mgr); sigset_t mask; sigemptyset(&mask); @@ -145,7 +147,8 @@ int od_instance_main(od_instance_t *instance, int argc, char **argv) /* create pid file */ if (instance->scheme.pid_file) od_pid_create(&instance->pid, instance->scheme.pid_file); - + /* seed id manager */ + od_idmgr_seed(&instance->id_mgr, &instance->log); /* run system services */ od_router_t router; od_periodic_t periodic; diff --git a/src/od_instance.h b/src/od_instance.h index 5d54b031..429dcdc4 100644 --- a/src/od_instance.h +++ b/src/od_instance.h @@ -16,6 +16,7 @@ struct od_instance od_log_t log; od_config_t config; od_scheme_t scheme; + od_idmgr_t id_mgr; }; void od_instance_init(od_instance_t*); diff --git a/src/od_log.c b/src/od_log.c index e3c6bd74..65af61a2 100644 --- a/src/od_log.c +++ b/src/od_log.c @@ -26,7 +26,6 @@ #include "od_pid.h" #include "od_syslog.h" #include "od_log.h" -#include "od_io.h" int od_log_init(od_log_t *log, od_pid_t *pid, od_syslog_t *syslog) { diff --git a/src/od_periodic.c b/src/od_periodic.c index a604be3c..b839cfe6 100644 --- a/src/od_periodic.c +++ b/src/od_periodic.c @@ -26,6 +26,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_msg.h" #include "od_system.h" #include "od_instance.h" diff --git a/src/od_pooler.c b/src/od_pooler.c index 2ead2b47..9192a837 100644 --- a/src/od_pooler.c +++ b/src/od_pooler.c @@ -28,6 +28,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_msg.h" #include "od_system.h" #include "od_instance.h" diff --git a/src/od_relay.c b/src/od_relay.c index d997ab61..7aca61f8 100644 --- a/src/od_relay.c +++ b/src/od_relay.c @@ -26,6 +26,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_msg.h" #include "od_system.h" #include "od_instance.h" diff --git a/src/od_relay_pool.c b/src/od_relay_pool.c index 752cdc1e..a3346ae5 100644 --- a/src/od_relay_pool.c +++ b/src/od_relay_pool.c @@ -26,6 +26,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_msg.h" #include "od_system.h" #include "od_instance.h" diff --git a/src/od_route_pool.c b/src/od_route_pool.c index 6f431d4c..eabcbc41 100644 --- a/src/od_route_pool.c +++ b/src/od_route_pool.c @@ -24,6 +24,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_system.h" #include "od_server.h" #include "od_server_pool.h" diff --git a/src/od_router.c b/src/od_router.c index 092034ba..01535861 100644 --- a/src/od_router.c +++ b/src/od_router.c @@ -26,6 +26,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_msg.h" #include "od_system.h" #include "od_instance.h" diff --git a/src/od_server_pool.c b/src/od_server_pool.c index b2700d5e..085b84ed 100644 --- a/src/od_server_pool.c +++ b/src/od_server_pool.c @@ -24,6 +24,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_system.h" #include "od_server.h" #include "od_server_pool.h" diff --git a/src/od_tls.c b/src/od_tls.c index af35af5c..50229883 100644 --- a/src/od_tls.c +++ b/src/od_tls.c @@ -26,6 +26,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_msg.h" #include "od_system.h" #include "od_instance.h" diff --git a/src/odissey.c b/src/odissey.c index cee8e7ad..063fad22 100644 --- a/src/odissey.c +++ b/src/odissey.c @@ -20,6 +20,7 @@ #include "od_scheme.h" #include "od_lex.h" #include "od_config.h" +#include "od_id.h" #include "od_instance.h" int main(int argc, char *argv[])