Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: connection monitor service #662 #234

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Authors from Codership Oy:
* Alexey Yurchenko <alexey.yurchenko@galeracluster.com>, Codership Oy
* Mario Karuza <mario.karuza@galeracluster.com>, Codership Oy
* Daniele Sciascia <daniele.sciascia@galeracluster.com>, Codership Oy
* Jan Lindström <jan.lindstrom@galeracluster.com>, Codership Oy
[Codership employees, add name and email/username above this line, but leave this line intact]

Other contributors:
Expand Down
69 changes: 69 additions & 0 deletions include/wsrep/connection_monitor_service.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2024-2026 Codership Oy <info@codership.com>
*
* This file is part of wsrep-lib.
*
* Wsrep-lib is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Wsrep-lib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
*/


/** @file connection_monitor_service.hpp
*
* Service interface for interacting with DBMS provided
* connection monitor callback.
*/

#ifndef WSREP_CONNECTION_MONITOR_SERVICE_HPP
#define WSREP_CONNECTION_MONITOR_SERVICE_HPP

#include "compiler.hpp"
#include "wsrep/buffer.hpp"
#include "v26/wsrep_connection_monitor_service.h"

namespace wsrep
{
class connection_monitor_service
{
public:

virtual ~connection_monitor_service() { }

/**
* Connection monitor connect callback.
*/
virtual bool connection_monitor_connect_cb(
wsrep_connection_key_t id,
const wsrep::const_buffer& scheme,
const wsrep::const_buffer& local_addr,
const wsrep::const_buffer& remote_addr
) WSREP_NOEXCEPT = 0;
/**
* Connection monitor disconnect callback.
*/
virtual bool connection_monitor_disconnect_cb(wsrep_connection_key_t id
) WSREP_NOEXCEPT=0;

/**
* Connection monitor SSL/TLS info callback.
*/
virtual bool connection_monitor_ssl_info_cb(wsrep_connection_key_t id,
const wsrep::const_buffer& ciper,
const wsrep::const_buffer& subject,
const wsrep::const_buffer& issuer,
const wsrep::const_buffer& version
) WSREP_NOEXCEPT = 0;
};
}

#endif // WSREP_CONNECTION_MONITOR_SERVICE_HPP
7 changes: 6 additions & 1 deletion include/wsrep/provider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ namespace wsrep
class tls_service;
class allowlist_service;
class event_service;
class connection_monitor_service;

class stid
{
Expand Down Expand Up @@ -450,6 +451,7 @@ namespace wsrep
wsrep::tls_service* tls_service;
wsrep::allowlist_service* allowlist_service;
wsrep::event_service* event_service;
wsrep::connection_monitor_service* connection_monitor_service;

// some GCC and clang versions don't support C++11 default
// initializers fully, so we need to use explicit constructors
Expand All @@ -461,17 +463,20 @@ namespace wsrep
, tls_service()
, allowlist_service()
, event_service()
, connection_monitor_service()
{
}

services(wsrep::thread_service* thr,
wsrep::tls_service* tls,
wsrep::allowlist_service* all,
wsrep::event_service* event)
wsrep::event_service* event,
wsrep::connection_monitor_service* con)
: thread_service(thr)
, tls_service(tls)
, allowlist_service(all)
, event_service(event)
, connection_monitor_service(con)
{
}
};
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_library(wsrep-lib
allowlist_service_v1.cpp
client_state.cpp
config_service_v1.cpp
connection_monitor_service_v1.cpp
event_service_v1.cpp
exception.cpp
gtid.cpp
Expand Down
142 changes: 142 additions & 0 deletions src/connection_monitor_service_v1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright (C) 2024-2025 Codership Oy <info@codership.com>
*
* This file is part of wsrep-lib.
*
* Wsrep-lib is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Wsrep-lib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
*/

#include "connection_monitor_service_v1.hpp"
#include "service_helpers.hpp"

#include "wsrep/buffer.hpp"
#include "v26/wsrep_connection_monitor_service.h"
#include "wsrep/connection_monitor_service.hpp"

#include <cassert>
#include <dlfcn.h>
#include <cerrno>

namespace wsrep_connection_monitor_service_v1
{
// Pointer to connection monitor service implementation provided by
// the application.
static wsrep::connection_monitor_service* connection_monitor_service_impl{ 0 };
static std::atomic<size_t> use_count;

//
// connection monitor service callbacks
//

void connection_monitor_connect_cb(
wsrep_connection_monitor_context_t*,
wsrep_connection_key_t id,
const wsrep_buf_t* scheme,
const wsrep_buf_t* local_address,
const wsrep_buf_t* remote_address
)
{
assert(connection_monitor_service_impl);
wsrep::const_buffer scheme_value(scheme->ptr, scheme->len);
wsrep::const_buffer remote_addr(remote_address->ptr, remote_address->len);
wsrep::const_buffer local_addr(local_address->ptr, local_address->len);
connection_monitor_service_impl->connection_monitor_connect_cb(
id,
scheme_value,
local_addr,
remote_addr);
}

void connection_monitor_disconnect_cb(
wsrep_connection_monitor_context_t*,
wsrep_connection_key_t id
)
{
assert(connection_monitor_service_impl);
connection_monitor_service_impl->connection_monitor_disconnect_cb(id);
}

void connection_monitor_ssl_info_cb(
wsrep_connection_monitor_context_t*,
wsrep_connection_key_t id,
const wsrep_buf_t* cipher,
const wsrep_buf_t* certificate_subject,
const wsrep_buf_t* certificate_issuer,
const wsrep_buf_t* version)
{
assert(connection_monitor_service_impl);
wsrep::const_buffer ssl_cipher(cipher->ptr, cipher->len);
wsrep::const_buffer cert_sub(certificate_subject->ptr, certificate_subject->len);
wsrep::const_buffer cert_iss(certificate_issuer->ptr, certificate_issuer->len);
wsrep::const_buffer vers(version->ptr, version->len);
connection_monitor_service_impl->connection_monitor_ssl_info_cb(
id, ssl_cipher, cert_sub, cert_iss, vers);
}

static wsrep_connection_monitor_service_v1_t connection_monitor_service_callbacks
= { connection_monitor_connect_cb,
connection_monitor_disconnect_cb,
connection_monitor_ssl_info_cb,
0 };
}

int wsrep::connection_monitor_service_v1_probe(void* dlh)
{
typedef int (*init_fn)(wsrep_connection_monitor_service_v1_t*);
typedef void (*deinit_fn)();
if (wsrep_impl::service_probe<init_fn>(
dlh, WSREP_CONNECTION_MONITOR_SERVICE_INIT_FUNC_V1, "connection monitor service v1") ||
wsrep_impl::service_probe<deinit_fn>(
dlh, WSREP_CONNECTION_MONITOR_SERVICE_DEINIT_FUNC_V1, "connection monitor service v1"))
{
wsrep::log_warning() << "Provider does not support connection monitor service v1";
return 1;
}

return 0;
}

int wsrep::connection_monitor_service_v1_init(void* dlh,
wsrep::connection_monitor_service* connection_service)
{
if (not (dlh && connection_service)) return EINVAL;
typedef int (*init_fn)(wsrep_connection_monitor_service_v1_t*);
wsrep_connection_monitor_service_v1::connection_monitor_service_impl = connection_service;
int ret(0);
if ((ret = wsrep_impl::service_init<init_fn>(
dlh, WSREP_CONNECTION_MONITOR_SERVICE_INIT_FUNC_V1,
&wsrep_connection_monitor_service_v1::connection_monitor_service_callbacks,
"connection monitor service v1")))
{
wsrep_connection_monitor_service_v1::connection_monitor_service_impl = 0;
}
else
{
++wsrep_connection_monitor_service_v1::use_count;
}
return ret;
}

void wsrep::connection_monitor_service_v1_deinit(void* dlh)
{
typedef int (*deinit_fn)();
wsrep_impl::service_deinit<deinit_fn>(
dlh, WSREP_CONNECTION_MONITOR_SERVICE_DEINIT_FUNC_V1, "connection monitor service v1");
assert(wsrep_connection_monitor_service_v1::use_count > 0);
--wsrep_connection_monitor_service_v1::use_count;
if (wsrep_connection_monitor_service_v1::use_count == 0)
{
wsrep_connection_monitor_service_v1::connection_monitor_service_impl = 0;
}
}
56 changes: 56 additions & 0 deletions src/connection_monitor_service_v1.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2024-2025 Codership Oy <info@codership.com>
*
* This file is part of wsrep-lib.
*
* Wsrep-lib is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Wsrep-lib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP
#define WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP

namespace wsrep
{
class connection_monitor_service;
/**
* Probe connection_monitor_service_v1 support in loaded library.
*
* @param dlh Handle returned by dlopen().
*
* @return Zero on success, non-zero system error code on failure.
*/
int connection_monitor_service_v1_probe(void *dlh);

/**
* Initialize the connection_monitor service.
*
* @param dlh Handle returned by dlopen().
* @param connection_monitor_service Pointer to
* wsrep::connection_monitor_service implementation.
*
* @return Zero on success, non-zero system error code on failure.
*/
int connection_monitor_service_v1_init(void* dlh,
wsrep::connection_monitor_service* connection_monitor_service);

/**
* Deinitialize the connection monitor service.
*
* @params dlh Handler returned by dlopen().
*/
void connection_monitor_service_v1_deinit(void* dlh);

}

#endif // WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP
29 changes: 29 additions & 0 deletions src/wsrep_provider_v26.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "wsrep/thread_service.hpp"
#include "wsrep/tls_service.hpp"
#include "wsrep/allowlist_service.hpp"
#include "wsrep/connection_monitor_service.hpp"

#include "service_helpers.hpp"
#include "thread_service_v1.hpp"
Expand All @@ -36,6 +37,7 @@
#include "event_service_v1.hpp"
#include "v26/wsrep_api.h"
#include "v26/wsrep_node_isolation.h"
#include "connection_monitor_service_v1.hpp"

#include <dlfcn.h>
#include <cassert>
Expand Down Expand Up @@ -674,6 +676,22 @@ namespace
}

wsrep_node_isolation_mode_set_fn_v1 node_isolation_mode_set;

static int init_connection_monitor_service(void* dlh,
wsrep::connection_monitor_service* connection_monitor_service)
{
assert(connection_monitor_service);
if (not wsrep::connection_monitor_service_v1_probe(dlh))
{
return wsrep::connection_monitor_service_v1_init(dlh, connection_monitor_service);
}
return 1;
}

static void deinit_connection_monitor_service(void* dlh)
{
wsrep::connection_monitor_service_v1_deinit(dlh);
}
}


Expand Down Expand Up @@ -721,6 +739,15 @@ void wsrep::wsrep_provider_v26::init_services(
node_isolation_mode_set
= wsrep_impl::resolve_function<wsrep_node_isolation_mode_set_fn_v1>(
wsrep_->dlh, WSREP_NODE_ISOLATION_MODE_SET_V1);

if (services.connection_monitor_service)
{
if (init_connection_monitor_service(wsrep_->dlh, services.connection_monitor_service))
{
throw wsrep::runtime_error("Failed to initialize connection monitor service");
}
services_enabled_.connection_monitor_service = services.connection_monitor_service;
}
}

void wsrep::wsrep_provider_v26::deinit_services()
Expand All @@ -734,6 +761,8 @@ void wsrep::wsrep_provider_v26::deinit_services()
if (services_enabled_.allowlist_service)
deinit_allowlist_service(wsrep_->dlh);
node_isolation_mode_set = nullptr;
if (services_enabled_.connection_monitor_service)
deinit_connection_monitor_service(wsrep_->dlh);
}

wsrep::wsrep_provider_v26::wsrep_provider_v26(
Expand Down
2 changes: 1 addition & 1 deletion wsrep-API/v26