Skip to content

Commit 4bfbd0b

Browse files
temeoayurchen
authored andcommitted
Wsrep-API TLS service interface.
This commit defines TLS service interface which can be used to delegate provider side network stream IO operations to application. This allows application to define transport security and authentication for cluster communication. Managing stream file descriptors (open, connect, accept, close) remains on provider side.
1 parent 12a50c4 commit 4bfbd0b

File tree

4 files changed

+346
-6
lines changed

4 files changed

+346
-6
lines changed

wsrep_api.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1365,7 +1365,8 @@ struct wsrep_st {
13651365
int wsrep_load(const char* spec, wsrep_t** hptr, wsrep_log_cb_t log_cb);
13661366

13671367
/*!
1368-
* @brief Unloads wsrep library and frees associated resources
1368+
* @brief Unloads the wsrep library. The application must call
1369+
* wsrep->free() before unload to release library side resources.
13691370
*
13701371
* @param hptr wsrep handler pointer
13711372
*/

wsrep_loader.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,16 @@ void wsrep_unload(wsrep_t *hptr)
224224
if (hptr->free)
225225
hptr->free(hptr);
226226
if (hptr->dlh)
227-
dlclose(hptr->dlh);
227+
{
228+
int err;
229+
if ((err = dlclose(hptr->dlh)))
230+
{
231+
char msg[1024];
232+
snprintf(msg, sizeof(msg), "dlclose(): %s", dlerror());
233+
msg[sizeof(msg) - 1] = '\0';
234+
logger(WSREP_LOG_WARN, msg);
235+
}
236+
}
228237
free(hptr);
229238
}
230239
}
231-

wsrep_thread_service.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@
3737
*
3838
* Version 1:
3939
* int wsrep_init_thread_service_v1(wsrep_thread_service_v1_t*)
40+
* void wsrep_deinit_thread_service_v1().
4041
*
4142
* The application defined implementation must be initialized before
42-
* calling the initialization function and must stay functional
43-
* until the provider is unloaded.
43+
* calling the provider initialization function via wsrep->init(). The
44+
* deinitialization must be done via deinit function after the
45+
* provider side resources have been released via wsrep->free().
4446
*/
4547

4648
#ifndef WSREP_THREAD_SERVICE_H
@@ -343,7 +345,11 @@ extern "C"
343345
#ifdef __cplusplus
344346
}
345347

346-
#define WSREP_THREAD_SERVICE_INIT_FUNC "wsrep_init_thread_service_v1"
348+
#define WSREP_THREAD_SERVICE_INIT_FUNC_V1 "wsrep_init_thread_service_v1"
349+
#define WSREP_THREAD_SERVICE_DEINIT_FUNC_V1 "wsrep_deinit_thread_service_v1"
350+
351+
/* For backwards compatibility. */
352+
#define WSREP_THREAD_SERVICE_INIT_FUNC WSREP_THREAD_SERVICE_INIT_FUNC_V1
347353

348354
#endif /* __cplusplus */
349355
#endif /* WSREP_THREAD_SERVICE_H */

wsrep_tls_service.h

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
/*
2+
* Copyright (C) 2020 Codership Oy <[email protected]>
3+
*
4+
* This file is part of wsrep-API.
5+
*
6+
* Wsrep-API 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-API 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-API. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
/** @file wsrep_tls_service.h
21+
*
22+
* This file defines interface for TLS services provided by the application,
23+
* used by the provider.
24+
*
25+
* In order to support both synchronous and asynchronous IO operations,
26+
* the interface is designed to work with sockets in both blocking
27+
* and non-blockig mode.
28+
*
29+
* The provider is in charge of opening and closing file
30+
* descriptors and connecting transport. After the connection has
31+
* been established, all further IO operations will be delegated
32+
* to the TLS service implementation which is provided by the application.
33+
*
34+
* The provider which is capable of using the service interface v1 must
35+
* export the following functions.
36+
*
37+
* int wsrep_init_tls_service_v1(wsrep_tls_service_v1_t*)
38+
* void wsrep_deinit_tls_service_v1()
39+
*
40+
* which can be probed by the application.
41+
*
42+
* The application must initialize the service via above init function
43+
* before the provider is initialized via wsrep->init(). The deinit
44+
* function must be called after the provider side resources have been
45+
* released via wsrep->free().
46+
*/
47+
48+
#ifndef WSREP_TLS_SERVICE_H
49+
#define WSREP_TLS_SERVICE_H
50+
51+
#include <sys/types.h> /* posix size_t */
52+
53+
#ifdef __cplusplus
54+
extern "C"
55+
{
56+
#endif /* __cplusplus */
57+
58+
/**
59+
* Type tag for application defined TLS context.
60+
*
61+
* Application may pass pointer to the context when initializing
62+
* TLS service. This pointer is passed a first parameter for
63+
* each service call.
64+
*/
65+
typedef struct wsrep_tls_context wsrep_tls_context_t;
66+
67+
/**
68+
* TLS stream structure.
69+
*/
70+
typedef struct wsrep_tls_stream_st
71+
{
72+
/**
73+
* File descriptor corresponding to the stream. The provider is
74+
* responsible in opening and closing the socket.
75+
*/
76+
int fd;
77+
/**
78+
* Opaque pointer reserved for application use.
79+
*/
80+
void* opaque;
81+
} wsrep_tls_stream_t;
82+
83+
/**
84+
* Enumeration for return codes.
85+
*/
86+
enum wsrep_tls_result
87+
{
88+
/**
89+
* The operation completed successfully, no further actions
90+
* are necessary.
91+
*/
92+
wsrep_tls_result_success = 0,
93+
/**
94+
* The operation completed successfully, but the application side wants
95+
* to make further reads. The provider must wait until the stream
96+
* becomes readable and then try the same operation again.
97+
*/
98+
wsrep_tls_result_want_read,
99+
/**
100+
* The operation completed successfully, but the application side wants
101+
* to make further writes. The provider must wait until the stream
102+
* becomes writable and then try the same operation again.
103+
*/
104+
wsrep_tls_result_want_write,
105+
/**
106+
* End of file was read from the stream. This result is needed to
107+
* make difference between graceful stream shutdown and zero length
108+
* reads which result from errors.
109+
*/
110+
wsrep_tls_result_eof,
111+
/**
112+
* An error occurred. The specific error reason must be
113+
* queried with wsrep_tls_stream_get_error_number and
114+
* wsrep_tls_stream_get_error_category.
115+
*/
116+
wsrep_tls_result_error
117+
};
118+
119+
/**
120+
* Initialize a new TLS stream.
121+
*
122+
* Initialize the stream for IO operations. During this call the
123+
* application must set up all of the data structures needed for
124+
* IO, but must not do any reads or writes into the stream yet.
125+
*
126+
* @param stream TLS stream to be initialized.
127+
*
128+
* @return Zero on success, system error number on error.
129+
*/
130+
typedef int (*wsrep_tls_stream_init_t)(wsrep_tls_context_t*,
131+
wsrep_tls_stream_t* stream);
132+
133+
/**
134+
* Deinitialize the TLS stream.
135+
*
136+
* Deinitialize the TLS stream and free all allocated resources.
137+
* Note that this function must not close the socket file descriptor
138+
* associated the the stream.
139+
*
140+
* @param stream Stream to be deinitialized.
141+
*/
142+
typedef void (*wsrep_tls_stream_deinit_t)(wsrep_tls_context_t*,
143+
wsrep_tls_stream_t* stream);
144+
145+
/**
146+
* Get error number of the last stream error. The error numbers are
147+
* defined by the application and must be integral type. By the convention
148+
* zero value must denote success.
149+
*
150+
* For managing errors other than system errors, the application may
151+
* provide several error categories via wsrep_tls_stream_get_error_category_t.
152+
*
153+
* @param stream TLS stream to get the last error from.
154+
*
155+
* @return Error number.
156+
*/
157+
typedef int (*wsrep_tls_stream_get_error_number_t)(
158+
wsrep_tls_context_t*,
159+
const wsrep_tls_stream_t* stream);
160+
161+
/**
162+
* Get the error category of the last stream error.
163+
*
164+
* The category is represented via a const void pointer to the provider.
165+
* If the category is NULL pointer, the error number is assumed to be
166+
* system error.
167+
*
168+
* @param stream Stream to get last error category from.
169+
*
170+
* @return Pointer to error category.
171+
*/
172+
typedef const void* (*wsrep_tls_stream_get_error_category_t)(
173+
wsrep_tls_context_t*,
174+
const wsrep_tls_stream_t* stream);
175+
176+
/**
177+
* Return human readable error message by error number and error
178+
* category.
179+
*
180+
* The message string returned by the application must contain only
181+
* printable characters and must be null terminated.
182+
*
183+
* @param error_number Error number returned by
184+
* wsrep_tls_stream_get_error_number_t.
185+
* @param category Error category returned by
186+
* wsrep_tls_stream_get_error_category_t.
187+
*
188+
* @return Human readable message string.
189+
*/
190+
typedef const char* (*wsrep_tls_error_message_get_t)(
191+
wsrep_tls_context_t*,
192+
int error_number, const void* category);
193+
194+
/**
195+
* Initiate TLS client side handshake. This function is called for the
196+
* stream sockets which have been connected by the provider.
197+
*
198+
* If the stream socket is in non-blocking mode, the call should return
199+
* immediately with appropriate result indicating if more actions are needed
200+
* in the case the operation would block. The provider will call this function
201+
* again until either a success or an error is returned.
202+
*
203+
* @param stream TLS stream.
204+
*
205+
* @return Enum wsrep_tls_result.
206+
*/
207+
typedef enum wsrep_tls_result (*wsrep_tls_stream_client_handshake_t)(
208+
wsrep_tls_context_t*,
209+
wsrep_tls_stream_t* stream);
210+
211+
/**
212+
* Initiate TLS server side handshake. This function is called for stream
213+
* sockets which have been accepted by the provider.
214+
*
215+
* If the stream socket is in non-blocking mode, the call should return
216+
* immediately with appropriate result indicating if more actions are needed
217+
* in the case the operation would block. The provider will call this function
218+
* again until either a success or an error is returned.
219+
*
220+
* @param stream TLS stream.
221+
*
222+
* @return Enum wsrep_tls_result.
223+
*/
224+
typedef enum wsrep_tls_result (*wsrep_tls_stream_server_handshake_t)(
225+
wsrep_tls_context_t*,
226+
wsrep_tls_stream_t* stream);
227+
228+
/**
229+
* Perform a read from the stream. If the file descriptor associated
230+
* to the stream is in non-blocking mode, the call must return immediately
231+
* with appropriate result if the stream processing would block.
232+
*
233+
* @param[in] stream TLS stream.
234+
* @param[in] buf Buffer to read the data into.
235+
* @param[in] max_count Maximum number of bytes to read.
236+
* @param[out] bytes_transferred Number of bytes read into the buffer during
237+
* the operation.
238+
*
239+
* @return Enum wsrep_tls_result.
240+
*/
241+
typedef enum wsrep_tls_result (*wsrep_tls_stream_read_t)(
242+
wsrep_tls_context_t*,
243+
wsrep_tls_stream_t* stream,
244+
void* buf,
245+
size_t max_count,
246+
size_t* bytes_transferred);
247+
248+
/**
249+
* Perform a write to the stream. If the file descriptor asociated to
250+
* te stream is in non-blocking mode, the call must return immediately
251+
* with appropriate result if the stream processing would block.
252+
*
253+
* @param[in] stream TLS stream.
254+
* @param[in] buf Buffer which contains the data to write.
255+
* @param[in] count Number of bytes to be written.
256+
* @param[out] bytes_transferred Number of bytes written into the stream
257+
* during the opration.
258+
*
259+
* @return Enum wsrep_tls_result.
260+
*/
261+
typedef enum wsrep_tls_result (*wsrep_tls_stream_write_t)(
262+
wsrep_tls_context_t*,
263+
wsrep_tls_stream_t* stream,
264+
const void* buf,
265+
size_t count,
266+
size_t* bytes_transferred);
267+
268+
/**
269+
* Shutdown the TLS stream.
270+
*
271+
* Note that the implementation must not close the associated stream
272+
* socket, just shut down the protocol.
273+
*
274+
* If the shutdown call returns either wsrep_result_want_read or
275+
* wsrep_result_want_write, the provider must wait until the socket
276+
* becomes readable or writable and then call the function again
277+
* until the return status is either success or an error occurs.
278+
*
279+
* @param stream TLS stream to be shut down.
280+
*
281+
* @return Enum wsrep_tls_result code.
282+
*
283+
*/
284+
typedef enum wsrep_tls_result (*wsrep_tls_stream_shutdown_t)(
285+
wsrep_tls_context_t*,
286+
wsrep_tls_stream_t* stream);
287+
288+
/**
289+
* TLS service struct.
290+
*
291+
* A pointer to this struct must be passed to the call to
292+
* wsrep_init_tls_service_v1.
293+
*
294+
* The application must provide implementation to all functions defined
295+
* in this struct.
296+
*/
297+
typedef struct wsrep_tls_service_v1_st
298+
{
299+
/* Stream */
300+
wsrep_tls_stream_init_t stream_init;
301+
wsrep_tls_stream_deinit_t stream_deinit;
302+
wsrep_tls_stream_get_error_number_t stream_get_error_number;
303+
wsrep_tls_stream_get_error_category_t stream_get_error_category;
304+
wsrep_tls_stream_client_handshake_t stream_client_handshake;
305+
wsrep_tls_stream_server_handshake_t stream_server_handshake;
306+
wsrep_tls_stream_read_t stream_read;
307+
wsrep_tls_stream_write_t stream_write;
308+
wsrep_tls_stream_shutdown_t stream_shutdown;
309+
/* Error */
310+
wsrep_tls_error_message_get_t error_message_get;
311+
/* Pointer to application defined TLS context. */
312+
wsrep_tls_context_t* context;
313+
} wsrep_tls_service_v1_t;
314+
315+
316+
#ifdef __cplusplus
317+
}
318+
#endif /* __cplusplus */
319+
320+
321+
#define WSREP_TLS_SERVICE_INIT_FUNC_V1 "wsrep_init_tls_service_v1"
322+
#define WSREP_TLS_SERVICE_DEINIT_FUNC_V1 "wsrep_deinit_tls_service_v1"
323+
324+
#endif /* WSREP_TLS_SERVICE_H */
325+

0 commit comments

Comments
 (0)