Skip to content

Commit

Permalink
Merge branch 'master' into add_groups
Browse files Browse the repository at this point in the history
  • Loading branch information
NikitaUnisikhin authored Feb 12, 2024
2 parents f9160fe + b80e5c1 commit a9398a9
Show file tree
Hide file tree
Showing 26 changed files with 458 additions and 23 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/coverity.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
name: coverity

on:
push:
branches: [ coverity_scan ]
schedule:
- cron: "0 0 * * *"

jobs:
scan:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'yandex' }}
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
steps:
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ Advanced multi-threaded PostgreSQL connection pooler and request router.

Odyssey is production-ready, it is being used in large production setups. We appreciate any kind of feedback and contribution to the project.

<a href="https://travis-ci.org/yandex/odyssey"><img src="https://travis-ci.org/yandex/odyssey.svg?branch=master" /></a>

<a href="https://scan.coverity.com/projects/yandex-odyssey">
<img alt="Coverity Scan Build Status"
src="https://scan.coverity.com/projects/20374/badge.svg"/>
Expand Down
2 changes: 1 addition & 1 deletion docker/bin/ody-stop
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/bin/bash
kill $(pgrep odyssey) || (sleep 1 && kill -9 $(pgrep odyssey)) || true
pkill odyssey || (sleep 1 && kill -9 $(pgrep odyssey)) || true
1 change: 1 addition & 0 deletions docker/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ ody-stop
/shell-test/console_role_test.sh
/shell-test/parse_pg_options_test.sh
/shell-test/override_pg_options_test.sh
/shell-test/pool_size_test.sh
ody-stop

ody-start
Expand Down
47 changes: 47 additions & 0 deletions docker/shell-test/pool_size.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
pid_file "/var/run/odyssey.pid"
daemonize yes

log_format "%p %t %l [%i %s] (%c) %m\n"

log_to_stdout yes

log_syslog no
log_syslog_ident "odyssey"
log_syslog_facility "daemon"

log_debug yes
log_config yes
log_session yes
log_query yes
log_stats yes


listen {
host "*"
port 6432
backlog 128
}


storage "postgres_server" {
type "remote"
host "localhost"
port 5432
}

database default {
user default {
authentication "none"
storage "postgres_server"
pool "transaction"
pool_size 10
pool_timeout 3000 # We expect 3 clients to do pg_sleep(1) each. Extra second to suppress falpping.
}
}

storage "local" {
type "local"
}


locks_dir "/tmp/odyssey"
23 changes: 23 additions & 0 deletions docker/shell-test/pool_size_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash -x
set -e
ody-stop

# We set pool size to 1 and check that 3 clients can do pg_sleep(1) at once.
# We expect them to wait serially on 1 backend.

/usr/bin/odyssey /shell-test/pool_size.conf


for _ in $(seq 1 300); do
psql -h 0.0.0.0 -p 6432 -c 'select pg_sleep(0.1)' -U user1 -d postgres &
done

for _ in $(seq 1 300); do
wait -n || {
code="$?"
([[ $code = "127" ]] && exit 0 || exit "$code")
break
}
done;

ody-stop
1 change: 1 addition & 0 deletions sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ set(od_src
hba_reader.c
hba_rule.c
group.c)
mdb_iamproxy.c)

if (PAM_FOUND)
list(APPEND od_src pam.c)
Expand Down
13 changes: 13 additions & 0 deletions sources/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,19 @@ static inline int od_auth_frontend_cleartext(od_client_t *client)

od_extention_t *extentions = client->global->extentions;

/* support mdb_iamproxy authentication */
if (client->rule->enable_mdb_iamproxy_auth) {
int authentication_result = mdb_iamproxy_authenticate_user(
client->startup.user.value, client_token.password,
instance, client);
kiwi_password_free(&client_token);
machine_msg_free(msg);
if (authentication_result != OK_RESPONSE) {
goto auth_failed; // refence at line 80, 100 and etc
}
return OK_RESPONSE;
}

#ifdef LDAP_FOUND
if (client->rule->ldap_endpoint_name) {
od_debug(&instance->logger, "auth", client, NULL,
Expand Down
16 changes: 11 additions & 5 deletions sources/auth_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ int od_auth_query(od_client_t *client, char *peer)
od_hash_t keyhash;
uint64_t current_time;

key.data = user->name;
key.len = user->name_len;
key.data = user->value;
key.len = user->value_len;

keyhash = od_murmur_hash(key.data, key.len);
/* acquire hash map entry lock */
Expand All @@ -139,12 +139,15 @@ int od_auth_query(od_client_t *client, char *peer)
current_time - cache_value->timestamp < 10 * interval_usec) {
od_debug(&instance->logger, "auth_query", NULL, NULL,
"reusing cached password for user %.*s",
user->name_len, user->name);
user->value_len, user->value);
/* unlock hashmap entry */
password->password_len = cache_value->passwd_len;
if (cache_value->passwd_len > 0) {
/* */
password->password = malloc(password->password_len + 1);
if (password->password == NULL) {
goto error;
}
strncpy(password->password, cache_value->passwd,
cache_value->passwd_len);
password->password[password->password_len] = '\0';
Expand All @@ -165,8 +168,8 @@ int od_auth_query(od_client_t *client, char *peer)
}

od_debug(&instance->logger, "auth_query", auth_client, NULL,
"acquiring password for user %.*s", user->name_len,
user->name);
"acquiring password for user %.*s", user->value_len,
user->value);

/* set auth query route user and database */
kiwi_var_set(&auth_client->startup.user, KIWI_VAR_UNDEF,
Expand Down Expand Up @@ -259,6 +262,9 @@ int od_auth_query(od_client_t *client, char *peer)
}
cache_value->passwd_len = password->password_len;
cache_value->passwd = malloc(password->password_len);
if (cache_value->passwd == NULL) {
goto error;
}
strncpy(cache_value->passwd, password->password,
cache_value->passwd_len);

Expand Down
7 changes: 7 additions & 0 deletions sources/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ struct od_client {
int ldap_storage_password_len;
char *ldap_auth_dn;
#endif

/* external_id for logging additional ifno about client */
char *external_id;
};

static const size_t OD_CLIENT_DEFAULT_HASHMAP_SZ = 420;
Expand Down Expand Up @@ -108,6 +111,7 @@ static inline void od_client_init(od_client_t *client)
client->ldap_storage_password_len = 0;
client->ldap_auth_dn = NULL;
#endif
client->external_id = NULL;

kiwi_be_startup_init(&client->startup);
kiwi_vars_init(&client->vars);
Expand Down Expand Up @@ -146,6 +150,9 @@ static inline void od_client_free(od_client_t *client)
if (client->prep_stmt_ids) {
od_hashmap_free(client->prep_stmt_ids);
}
if (client->external_id) {
free(client->external_id);
}
free(client);
}

Expand Down
1 change: 1 addition & 0 deletions sources/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ od_config_listen_t *od_config_listen_add(od_config_t *config)

listen->tls_opts = od_tls_opts_alloc();
if (listen->tls_opts == NULL) {
free(listen);
return NULL;
}

Expand Down
19 changes: 19 additions & 0 deletions sources/config_reader.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ typedef enum {
OD_LAUTH_QUERY_USER,
OD_LAUTH_LDAP_SERVICE,
OD_LAUTH_PASSWORD_PASSTHROUGH,
OD_LAUTH_MDB_IAMPROXY_ENABLE,
OD_LAUTH_MDB_IAMPROXY_SOCKET_PATH,
OD_LQUANTILES,
OD_LMODULE,
OD_LLDAP_ENDPOINT,
Expand Down Expand Up @@ -281,6 +283,9 @@ static od_keyword_t od_config_keywords[] = {
od_keyword("password_passthrough", OD_LAUTH_PASSWORD_PASSTHROUGH),
od_keyword("load_module", OD_LMODULE),
od_keyword("hba_file", OD_LHBA_FILE),
od_keyword("enable_mdb_iamproxy_auth", OD_LAUTH_MDB_IAMPROXY_ENABLE),
od_keyword("mdb_iamproxy_socket_path",
OD_LAUTH_MDB_IAMPROXY_SOCKET_PATH),

/* ldap */
od_keyword("ldap_endpoint", OD_LLDAP_ENDPOINT),
Expand Down Expand Up @@ -1211,6 +1216,7 @@ static int od_config_reader_rule_settings(od_config_reader_t *reader,
od_extention_t *extentions,
od_storage_watchdog_t *watchdog)
{
rule->mdb_iamproxy_socket_path = NULL;
for (;;) {
od_token_t token;
int rc;
Expand Down Expand Up @@ -1299,6 +1305,19 @@ static int od_config_reader_rule_settings(od_config_reader_t *reader,
&rule->auth_module))
return NOT_OK_RESPONSE;
break;
/* mdb_iamproxy authentication */
case OD_LAUTH_MDB_IAMPROXY_ENABLE: {
if (!od_config_reader_yes_no(
reader, &rule->enable_mdb_iamproxy_auth))
return NOT_OK_RESPONSE;
break;
}
case OD_LAUTH_MDB_IAMPROXY_SOCKET_PATH: {
if (!od_config_reader_string(
reader, &rule->mdb_iamproxy_socket_path))
return NOT_OK_RESPONSE;
break;
}
#ifdef PAM_FOUND
/* auth_pam_service */
case OD_LAUTH_PAM_SERVICE:
Expand Down
1 change: 1 addition & 0 deletions sources/counter.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ od_bucket_t *od_bucket_create(void)
return b;
}

free(b);
return NULL;
}

Expand Down
11 changes: 7 additions & 4 deletions sources/frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,7 @@ static od_frontend_status_t od_frontend_remote_client(od_relay_t *relay,

od_frontend_status_t retstatus = OD_OK;
machine_msg_t *msg;
msg = NULL;
bool forwarded = 0;
switch (type) {
case KIWI_FE_COPY_DONE:
Expand Down Expand Up @@ -1513,7 +1514,8 @@ static od_frontend_status_t od_frontend_remote_client(od_relay_t *relay,
}

/* If the retstatus is not SKIP */
if (route->rule->pool->reserve_prepared_statement && forwarded != 1) {
if (route->rule->pool->reserve_prepared_statement && forwarded != 1 &&
msg != NULL) {
msg = kiwi_fe_copy_msg(msg, data, size);
od_write(&server->io, msg);
retstatus = OD_SKIP;
Expand Down Expand Up @@ -1559,8 +1561,9 @@ static inline od_frontend_status_t od_frontend_poll_catchup(od_client_t *client,
int absent_heartbeat_checks = 0;
while (route->last_heartbeat == 0) {
machine_sleep(ODYSSEY_CATCHUP_RECHECK_INTERVAL);
if (absent_heartbeat_checks++ >
(timeout * 1000 / ODYSSEY_CATCHUP_RECHECK_INTERVAL)) {
if ((int64_t)absent_heartbeat_checks++ > // add cast to int64_t for correct camparison (int64_t > int and ibt64_t > uint32_t)
(int64_t)(timeout * 1000 /
ODYSSEY_CATCHUP_RECHECK_INTERVAL)) {
od_debug(&instance->logger, "catchup", client, NULL,
"No heartbeat for route detected\n");
return OD_ECATCHUP_TIMEOUT;
Expand Down Expand Up @@ -2338,4 +2341,4 @@ void od_frontend(void *arg)
od_router_unroute(router, client);
/* close frontend connection */
od_frontend_close(client);
}
}
2 changes: 2 additions & 0 deletions sources/hashmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ od_hashmap_t *od_hashmap_create(size_t sz)

for (size_t i = 0; i < sz; ++i) {
if (od_hash_bucket_init(&hm->buckets[i]) == NOT_OK_RESPONSE) {
free(hm->buckets);
free(hm);
return NULL;
}
Expand Down Expand Up @@ -249,6 +250,7 @@ od_hashmap_elt_t *od_hashmap_lock_key(od_hashmap_t *hm, od_hash_t keyhash,
int od_hashmap_unlock_key(od_hashmap_t *hm, od_hash_t keyhash,
od_hashmap_elt_t *key)
{
(void)key;
size_t bucket_index = keyhash % hm->size;
pthread_mutex_unlock(&hm->buckets[bucket_index]->mu);
return 0 /* OK */;
Expand Down
1 change: 0 additions & 1 deletion sources/instance.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ void od_config_testing(od_instance_t *instance)

error:
od_router_free(&router);
return NOT_OK_RESPONSE;
}

static inline void od_bind_version()
Expand Down
17 changes: 17 additions & 0 deletions sources/logger.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,23 @@ od_logger_format(od_logger_t *logger, od_logger_level_t level, char *context,
if (od_unlikely(format_pos == format_end))
break;
switch (*format_pos) {
/* external_id */
case 'x': {
if (client && client->external_id != NULL) {
len = od_snprintf(dst_pos,
dst_end - dst_pos,
"%s",
client->external_id);
dst_pos += len;
break;
}

// fall throught fix (if client is not defined will write 'none' to log file)
len = od_snprintf(dst_pos, dst_end - dst_pos,
"none");
dst_pos += len;
break;
}
/* unixtime */
case 'n': {
time_t tm = time(NULL);
Expand Down
Loading

0 comments on commit a9398a9

Please sign in to comment.