Skip to content

Commit 9f5c99e

Browse files
committed
MDEV-26851 : Add interface to monitor connections in Galera
1 parent 31db847 commit 9f5c99e

8 files changed

+305
-2
lines changed

CONTRIBUTORS.txt

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Authors from Codership Oy:
2222
* Alexey Yurchenko <[email protected]>, Codership Oy
2323
* Mario Karuza <[email protected]>, Codership Oy
2424
* Daniele Sciascia <[email protected]>, Codership Oy
25+
* Jan Lindström <[email protected]>, Codership Oy
2526
[Codership employees, add name and email/username above this line, but leave this line intact]
2627

2728
Other contributors:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (C) 2024-2026 Codership Oy <[email protected]>
3+
*
4+
* This file is part of wsrep-lib.
5+
*
6+
* Wsrep-lib is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 2 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Wsrep-lib is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
21+
/** @file connection_monitor_service.hpp
22+
*
23+
* Service interface for interacting with DBMS provided
24+
* connection monitor callback.
25+
*/
26+
27+
#ifndef WSREP_CONNECTION_MONITOR_SERVICE_HPP
28+
#define WSREP_CONNECTION_MONITOR_SERVICE_HPP
29+
30+
#include "compiler.hpp"
31+
#include "wsrep/buffer.hpp"
32+
#include "v26/wsrep_connection_monitor_service.h"
33+
34+
namespace wsrep
35+
{
36+
class connection_monitor_service
37+
{
38+
public:
39+
40+
virtual ~connection_monitor_service() { }
41+
42+
/**
43+
* Connection monitor connect callback.
44+
*/
45+
virtual bool connection_monitor_connect_cb(
46+
wsrep_connection_key_t id,
47+
const wsrep::const_buffer& scheme,
48+
const wsrep::const_buffer& local_addr,
49+
const wsrep::const_buffer& remote_addr
50+
) WSREP_NOEXCEPT = 0;
51+
/**
52+
* Connection monitor disconnect callback.
53+
*/
54+
virtual bool connection_monitor_disconnect_cb(wsrep_connection_key_t id
55+
) WSREP_NOEXCEPT=0;
56+
57+
/**
58+
* Connection monitor SSL/TLS info callback.
59+
*/
60+
virtual bool connection_monitor_ssl_info_cb(wsrep_connection_key_t id,
61+
const wsrep::const_buffer& ciper,
62+
const wsrep::const_buffer& subject,
63+
const wsrep::const_buffer& issuer,
64+
const wsrep::const_buffer& version
65+
) WSREP_NOEXCEPT = 0;
66+
};
67+
}
68+
69+
#endif // WSREP_CONNECTION_MONITOR_SERVICE_HPP

include/wsrep/provider.hpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ namespace wsrep
4747
class tls_service;
4848
class allowlist_service;
4949
class event_service;
50+
class connection_monitor_service;
5051

5152
class stid
5253
{
@@ -450,6 +451,7 @@ namespace wsrep
450451
wsrep::tls_service* tls_service;
451452
wsrep::allowlist_service* allowlist_service;
452453
wsrep::event_service* event_service;
454+
wsrep::connection_monitor_service* connection_monitor_service;
453455

454456
// some GCC and clang versions don't support C++11 default
455457
// initializers fully, so we need to use explicit constructors
@@ -461,17 +463,20 @@ namespace wsrep
461463
, tls_service()
462464
, allowlist_service()
463465
, event_service()
466+
, connection_monitor_service()
464467
{
465468
}
466469

467470
services(wsrep::thread_service* thr,
468471
wsrep::tls_service* tls,
469472
wsrep::allowlist_service* all,
470-
wsrep::event_service* event)
473+
wsrep::event_service* event,
474+
wsrep::connection_monitor_service* con)
471475
: thread_service(thr)
472476
, tls_service(tls)
473477
, allowlist_service(all)
474478
, event_service(event)
479+
, connection_monitor_service(con)
475480
{
476481
}
477482
};

src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_library(wsrep-lib
66
allowlist_service_v1.cpp
77
client_state.cpp
88
config_service_v1.cpp
9+
connection_monitor_service_v1.cpp
910
event_service_v1.cpp
1011
exception.cpp
1112
gtid.cpp

src/connection_monitor_service_v1.cpp

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* Copyright (C) 2024-2025 Codership Oy <[email protected]>
3+
*
4+
* This file is part of wsrep-lib.
5+
*
6+
* Wsrep-lib is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 2 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Wsrep-lib is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
#include "connection_monitor_service_v1.hpp"
21+
#include "service_helpers.hpp"
22+
23+
#include "wsrep/buffer.hpp"
24+
#include "v26/wsrep_connection_monitor_service.h"
25+
#include "wsrep/connection_monitor_service.hpp"
26+
27+
#include <cassert>
28+
#include <dlfcn.h>
29+
#include <cerrno>
30+
31+
namespace wsrep_connection_monitor_service_v1
32+
{
33+
// Pointer to connection monitor service implementation provided by
34+
// the application.
35+
static wsrep::connection_monitor_service* connection_monitor_service_impl{ 0 };
36+
static std::atomic<size_t> use_count;
37+
38+
//
39+
// connection monitor service callbacks
40+
//
41+
42+
void connection_monitor_connect_cb(
43+
wsrep_connection_monitor_context_t*,
44+
wsrep_connection_key_t id,
45+
const wsrep_buf_t* scheme,
46+
const wsrep_buf_t* local_address,
47+
const wsrep_buf_t* remote_address
48+
)
49+
{
50+
assert(connection_monitor_service_impl);
51+
wsrep::const_buffer scheme_value(scheme->ptr, scheme->len);
52+
wsrep::const_buffer remote_addr(remote_address->ptr, remote_address->len);
53+
wsrep::const_buffer local_addr(local_address->ptr, local_address->len);
54+
connection_monitor_service_impl->connection_monitor_connect_cb(
55+
id,
56+
scheme_value,
57+
local_addr,
58+
remote_addr);
59+
}
60+
61+
void connection_monitor_disconnect_cb(
62+
wsrep_connection_monitor_context_t*,
63+
wsrep_connection_key_t id
64+
)
65+
{
66+
assert(connection_monitor_service_impl);
67+
connection_monitor_service_impl->connection_monitor_disconnect_cb(id);
68+
}
69+
70+
void connection_monitor_ssl_info_cb(
71+
wsrep_connection_monitor_context_t*,
72+
wsrep_connection_key_t id,
73+
const wsrep_buf_t* cipher,
74+
const wsrep_buf_t* certificate_subject,
75+
const wsrep_buf_t* certificate_issuer,
76+
const wsrep_buf_t* version)
77+
{
78+
assert(connection_monitor_service_impl);
79+
wsrep::const_buffer ssl_cipher(cipher->ptr, cipher->len);
80+
wsrep::const_buffer cert_sub(certificate_subject->ptr, certificate_subject->len);
81+
wsrep::const_buffer cert_iss(certificate_issuer->ptr, certificate_issuer->len);
82+
wsrep::const_buffer vers(version->ptr, version->len);
83+
connection_monitor_service_impl->connection_monitor_ssl_info_cb(
84+
id, ssl_cipher, cert_sub, cert_iss, vers);
85+
}
86+
87+
static wsrep_connection_monitor_service_v1_t connection_monitor_service_callbacks
88+
= { connection_monitor_connect_cb,
89+
connection_monitor_disconnect_cb,
90+
connection_monitor_ssl_info_cb,
91+
0 };
92+
}
93+
94+
int wsrep::connection_monitor_service_v1_probe(void* dlh)
95+
{
96+
typedef int (*init_fn)(wsrep_connection_monitor_service_v1_t*);
97+
typedef void (*deinit_fn)();
98+
if (wsrep_impl::service_probe<init_fn>(
99+
dlh, WSREP_CONNECTION_MONITOR_SERVICE_INIT_FUNC_V1, "connection monitor service v1") ||
100+
wsrep_impl::service_probe<deinit_fn>(
101+
dlh, WSREP_CONNECTION_MONITOR_SERVICE_DEINIT_FUNC_V1, "connection monitor service v1"))
102+
{
103+
wsrep::log_warning() << "Provider does not support connection monitor service v1";
104+
return 1;
105+
}
106+
107+
return 0;
108+
}
109+
110+
int wsrep::connection_monitor_service_v1_init(void* dlh,
111+
wsrep::connection_monitor_service* connection_service)
112+
{
113+
if (not (dlh && connection_service)) return EINVAL;
114+
typedef int (*init_fn)(wsrep_connection_monitor_service_v1_t*);
115+
wsrep_connection_monitor_service_v1::connection_monitor_service_impl = connection_service;
116+
int ret(0);
117+
if ((ret = wsrep_impl::service_init<init_fn>(
118+
dlh, WSREP_CONNECTION_MONITOR_SERVICE_INIT_FUNC_V1,
119+
&wsrep_connection_monitor_service_v1::connection_monitor_service_callbacks,
120+
"connection monitor service v1")))
121+
{
122+
wsrep_connection_monitor_service_v1::connection_monitor_service_impl = 0;
123+
}
124+
else
125+
{
126+
++wsrep_connection_monitor_service_v1::use_count;
127+
}
128+
return ret;
129+
}
130+
131+
void wsrep::connection_monitor_service_v1_deinit(void* dlh)
132+
{
133+
typedef int (*deinit_fn)();
134+
wsrep_impl::service_deinit<deinit_fn>(
135+
dlh, WSREP_CONNECTION_MONITOR_SERVICE_DEINIT_FUNC_V1, "connection monitor service v1");
136+
assert(wsrep_connection_monitor_service_v1::use_count > 0);
137+
--wsrep_connection_monitor_service_v1::use_count;
138+
if (wsrep_connection_monitor_service_v1::use_count == 0)
139+
{
140+
wsrep_connection_monitor_service_v1::connection_monitor_service_impl = 0;
141+
}
142+
}

src/connection_monitor_service_v1.hpp

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (C) 2024-2025 Codership Oy <[email protected]>
3+
*
4+
* This file is part of wsrep-lib.
5+
*
6+
* Wsrep-lib is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 2 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Wsrep-lib is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
#ifndef WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP
21+
#define WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP
22+
23+
namespace wsrep
24+
{
25+
class connection_monitor_service;
26+
/**
27+
* Probe connection_monitor_service_v1 support in loaded library.
28+
*
29+
* @param dlh Handle returned by dlopen().
30+
*
31+
* @return Zero on success, non-zero system error code on failure.
32+
*/
33+
int connection_monitor_service_v1_probe(void *dlh);
34+
35+
/**
36+
* Initialize the connection_monitor service.
37+
*
38+
* @param dlh Handle returned by dlopen().
39+
* @param connection_monitor_service Pointer to
40+
* wsrep::connection_monitor_service implementation.
41+
*
42+
* @return Zero on success, non-zero system error code on failure.
43+
*/
44+
int connection_monitor_service_v1_init(void* dlh,
45+
wsrep::connection_monitor_service* connection_monitor_service);
46+
47+
/**
48+
* Deinitialize the connection monitor service.
49+
*
50+
* @params dlh Handler returned by dlopen().
51+
*/
52+
void connection_monitor_service_v1_deinit(void* dlh);
53+
54+
}
55+
56+
#endif // WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP

src/wsrep_provider_v26.cpp

+29
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "wsrep/thread_service.hpp"
2929
#include "wsrep/tls_service.hpp"
3030
#include "wsrep/allowlist_service.hpp"
31+
#include "wsrep/connection_monitor_service.hpp"
3132

3233
#include "service_helpers.hpp"
3334
#include "thread_service_v1.hpp"
@@ -36,6 +37,7 @@
3637
#include "event_service_v1.hpp"
3738
#include "v26/wsrep_api.h"
3839
#include "v26/wsrep_node_isolation.h"
40+
#include "connection_monitor_service_v1.hpp"
3941

4042
#include <dlfcn.h>
4143
#include <cassert>
@@ -674,6 +676,22 @@ namespace
674676
}
675677

676678
wsrep_node_isolation_mode_set_fn_v1 node_isolation_mode_set;
679+
680+
static int init_connection_monitor_service(void* dlh,
681+
wsrep::connection_monitor_service* connection_monitor_service)
682+
{
683+
assert(connection_monitor_service);
684+
if (not wsrep::connection_monitor_service_v1_probe(dlh))
685+
{
686+
return wsrep::connection_monitor_service_v1_init(dlh, connection_monitor_service);
687+
}
688+
return 1;
689+
}
690+
691+
static void deinit_connection_monitor_service(void* dlh)
692+
{
693+
wsrep::connection_monitor_service_v1_deinit(dlh);
694+
}
677695
}
678696

679697

@@ -721,6 +739,15 @@ void wsrep::wsrep_provider_v26::init_services(
721739
node_isolation_mode_set
722740
= wsrep_impl::resolve_function<wsrep_node_isolation_mode_set_fn_v1>(
723741
wsrep_->dlh, WSREP_NODE_ISOLATION_MODE_SET_V1);
742+
743+
if (services.connection_monitor_service)
744+
{
745+
if (init_connection_monitor_service(wsrep_->dlh, services.connection_monitor_service))
746+
{
747+
throw wsrep::runtime_error("Failed to initialize connection monitor service");
748+
}
749+
services_enabled_.connection_monitor_service = services.connection_monitor_service;
750+
}
724751
}
725752

726753
void wsrep::wsrep_provider_v26::deinit_services()
@@ -734,6 +761,8 @@ void wsrep::wsrep_provider_v26::deinit_services()
734761
if (services_enabled_.allowlist_service)
735762
deinit_allowlist_service(wsrep_->dlh);
736763
node_isolation_mode_set = nullptr;
764+
if (services_enabled_.connection_monitor_service)
765+
deinit_connection_monitor_service(wsrep_->dlh);
737766
}
738767

739768
wsrep::wsrep_provider_v26::wsrep_provider_v26(

0 commit comments

Comments
 (0)