1 /*
2  * Copyright (c) 2015-2017 Red Hat, Inc.
3  *
4  * All rights reserved.
5  *
6  * Author: Jan Friesse (jfriesse@redhat.com)
7  *
8  * This software licensed under BSD license, the text of which follows:
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * - Redistributions of source code must retain the above copyright notice,
14  *   this list of conditions and the following disclaimer.
15  * - Redistributions in binary form must reproduce the above copyright notice,
16  *   this list of conditions and the following disclaimer in the documentation
17  *   and/or other materials provided with the distribution.
18  * - Neither the name of the Red Hat, Inc. nor the names of its
19  *   contributors may be used to endorse or promote products derived from this
20  *   software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32  * THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #ifndef _TLV_H_
36 #define _TLV_H_
37 
38 #include <sys/types.h>
39 #include <inttypes.h>
40 
41 #include "dynar.h"
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 enum tlv_opt_type {
48 	TLV_OPT_MSG_SEQ_NUMBER = 0,
49 	TLV_OPT_CLUSTER_NAME = 1,
50 	TLV_OPT_TLS_SUPPORTED = 2,
51 	TLV_OPT_TLS_CLIENT_CERT_REQUIRED = 3,
52 	TLV_OPT_SUPPORTED_MESSAGES = 4,
53 	TLV_OPT_SUPPORTED_OPTIONS = 5,
54 	TLV_OPT_REPLY_ERROR_CODE = 6,
55 	TLV_OPT_SERVER_MAXIMUM_REQUEST_SIZE = 7,
56 	TLV_OPT_SERVER_MAXIMUM_REPLY_SIZE = 8,
57 	TLV_OPT_NODE_ID = 9,
58 	TLV_OPT_SUPPORTED_DECISION_ALGORITHMS = 10,
59 	TLV_OPT_DECISION_ALGORITHM = 11,
60 	TLV_OPT_HEARTBEAT_INTERVAL = 12,
61 	TLV_OPT_RING_ID = 13,
62 	TLV_OPT_CONFIG_VERSION = 14,
63 	TLV_OPT_DATA_CENTER_ID = 15,
64 	TLV_OPT_NODE_STATE = 16,
65 	TLV_OPT_NODE_INFO = 17,
66 	TLV_OPT_NODE_LIST_TYPE = 18,
67 	TLV_OPT_VOTE = 19,
68 	TLV_OPT_QUORATE = 20,
69 	TLV_OPT_TIE_BREAKER = 21,
70 	TLV_OPT_HEURISTICS = 22,
71 };
72 
73 enum tlv_tls_supported {
74 	TLV_TLS_UNSUPPORTED = 0,
75 	TLV_TLS_SUPPORTED = 1,
76 	TLV_TLS_REQUIRED = 2,
77 };
78 
79 enum tlv_reply_error_code {
80 	TLV_REPLY_ERROR_CODE_NO_ERROR = 0,
81 	TLV_REPLY_ERROR_CODE_UNSUPPORTED_NEEDED_MESSAGE = 1,
82 	TLV_REPLY_ERROR_CODE_UNSUPPORTED_NEEDED_OPTION = 2,
83 	TLV_REPLY_ERROR_CODE_TLS_REQUIRED = 3,
84 	TLV_REPLY_ERROR_CODE_UNSUPPORTED_MESSAGE = 4,
85 	TLV_REPLY_ERROR_CODE_MESSAGE_TOO_LONG = 5,
86 	TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED = 6,
87 	TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION = 7,
88 	TLV_REPLY_ERROR_CODE_UNEXPECTED_MESSAGE = 8,
89 	TLV_REPLY_ERROR_CODE_ERROR_DECODING_MSG = 9,
90 	TLV_REPLY_ERROR_CODE_INTERNAL_ERROR = 10,
91 	TLV_REPLY_ERROR_CODE_INIT_REQUIRED = 11,
92 	TLV_REPLY_ERROR_CODE_UNSUPPORTED_DECISION_ALGORITHM = 12,
93 	TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL = 13,
94 	TLV_REPLY_ERROR_CODE_UNSUPPORTED_DECISION_ALGORITHM_MESSAGE = 14,
95 	TLV_REPLY_ERROR_CODE_TIE_BREAKER_DIFFERS_FROM_OTHER_NODES = 15,
96 	TLV_REPLY_ERROR_CODE_ALGORITHM_DIFFERS_FROM_OTHER_NODES = 16,
97 	TLV_REPLY_ERROR_CODE_DUPLICATE_NODE_ID = 17,
98 	TLV_REPLY_ERROR_CODE_INVALID_CONFIG_NODE_LIST = 18,
99 	TLV_REPLY_ERROR_CODE_INVALID_MEMBERSHIP_NODE_LIST = 19,
100 };
101 
102 enum tlv_decision_algorithm_type {
103 	TLV_DECISION_ALGORITHM_TYPE_TEST = 0,
104 	TLV_DECISION_ALGORITHM_TYPE_FFSPLIT = 1,
105 	TLV_DECISION_ALGORITHM_TYPE_2NODELMS = 2,
106 	TLV_DECISION_ALGORITHM_TYPE_LMS = 3,
107 };
108 
109 struct tlv_ring_id {
110 	uint32_t node_id;
111 	uint64_t seq;
112 };
113 
114 enum tlv_node_state {
115 	TLV_NODE_STATE_NOT_SET = 0,
116 	TLV_NODE_STATE_MEMBER = 1,
117 	TLV_NODE_STATE_DEAD = 2,
118 	TLV_NODE_STATE_LEAVING = 3,
119 };
120 
121 enum tlv_node_list_type {
122 	TLV_NODE_LIST_TYPE_INITIAL_CONFIG = 0,
123 	TLV_NODE_LIST_TYPE_CHANGED_CONFIG = 1,
124 	TLV_NODE_LIST_TYPE_MEMBERSHIP = 2,
125 	TLV_NODE_LIST_TYPE_QUORUM = 3,
126 };
127 
128 enum tlv_vote {
129 	TLV_VOTE_UNDEFINED = 0,
130 	TLV_VOTE_ACK = 1,
131 	TLV_VOTE_NACK = 2,
132 	TLV_VOTE_ASK_LATER = 3,
133 	TLV_VOTE_WAIT_FOR_REPLY = 4,
134 	TLV_VOTE_NO_CHANGE = 5,
135 };
136 
137 enum tlv_quorate {
138 	TLV_QUORATE_INQUORATE = 0,
139 	TLV_QUORATE_QUORATE = 1,
140 };
141 
142 enum tlv_tie_breaker_mode {
143 	TLV_TIE_BREAKER_MODE_LOWEST = 1,
144 	TLV_TIE_BREAKER_MODE_HIGHEST = 2,
145 	TLV_TIE_BREAKER_MODE_NODE_ID = 3,
146 };
147 
148 struct tlv_tie_breaker {
149 	enum tlv_tie_breaker_mode mode;
150 	uint32_t node_id;
151 };
152 
153 struct tlv_node_info {
154 	uint32_t node_id;
155 	uint32_t data_center_id;		/* 0 - data center id was not set */
156 	enum tlv_node_state node_state;		/* TLV_NODE_STATE_NOT_SET - state was not set */
157 };
158 
159 enum tlv_heuristics {
160 	TLV_HEURISTICS_UNDEFINED = 0,
161 	TLV_HEURISTICS_PASS = 1,
162 	TLV_HEURISTICS_FAIL = 2,
163 };
164 
165 struct tlv_iterator {
166 	const char *msg;
167 	size_t msg_len;
168 	size_t current_pos;
169 	size_t msg_header_len;
170 	int iter_next_called;
171 };
172 
173 extern int			 tlv_add(struct dynar *msg, enum tlv_opt_type opt_type,
174     uint16_t opt_len, const void *value);
175 
176 extern int			 tlv_add_u32(struct dynar *msg, enum tlv_opt_type opt_type,
177     uint32_t u32);
178 
179 extern int			 tlv_add_u8(struct dynar *msg, enum tlv_opt_type opt_type,
180     uint8_t u8);
181 
182 extern int			 tlv_add_u16(struct dynar *msg, enum tlv_opt_type opt_type,
183     uint16_t u16);
184 
185 extern int			 tlv_add_u64(struct dynar *msg, enum tlv_opt_type opt_type,
186     uint64_t u64);
187 
188 extern int			 tlv_add_string(struct dynar *msg, enum tlv_opt_type opt_type,
189     const char *str);
190 
191 extern int			 tlv_add_u16_array(struct dynar *msg, enum tlv_opt_type opt_type,
192     const uint16_t *array, size_t array_size);
193 
194 extern int			 tlv_add_supported_options(struct dynar *msg,
195     const enum tlv_opt_type *supported_options, size_t no_supported_options);
196 
197 extern int			 tlv_add_msg_seq_number(struct dynar *msg,
198     uint32_t msg_seq_number);
199 
200 extern int			 tlv_add_cluster_name(struct dynar *msg, const char *cluster_name);
201 
202 extern int			 tlv_add_tls_supported(struct dynar *msg,
203     enum tlv_tls_supported tls_supported);
204 
205 extern int			 tlv_add_tls_client_cert_required(struct dynar *msg,
206     int tls_client_cert_required);
207 
208 extern int			 tlv_add_reply_error_code(struct dynar *msg,
209     enum tlv_reply_error_code error_code);
210 
211 extern int			 tlv_add_node_id(struct dynar *msg, uint32_t node_id);
212 
213 extern int			 tlv_add_server_maximum_request_size(struct dynar *msg,
214     size_t server_maximum_request_size);
215 
216 extern int			 tlv_add_server_maximum_reply_size(struct dynar *msg,
217     size_t server_maximum_reply_size);
218 
219 extern int			 tlv_add_supported_decision_algorithms(struct dynar *msg,
220     const enum tlv_decision_algorithm_type *supported_algorithms, size_t no_supported_algorithms);
221 
222 extern int			 tlv_add_decision_algorithm(struct dynar *msg,
223     enum tlv_decision_algorithm_type decision_algorithm);
224 
225 extern int			 tlv_add_heartbeat_interval(struct dynar *msg,
226     uint32_t heartbeat_interval);
227 
228 extern int			 tlv_add_ring_id(struct dynar *msg,
229     const struct tlv_ring_id *ring_id);
230 
231 extern int			 tlv_add_tie_breaker(struct dynar *msg,
232     const struct tlv_tie_breaker *tie_breaker);
233 
234 extern int			 tlv_add_config_version(struct dynar *msg,
235     uint64_t config_version);
236 
237 extern int			 tlv_add_data_center_id(struct dynar *msg,
238     uint32_t data_center_id);
239 
240 extern int			 tlv_add_node_state(struct dynar *msg,
241     enum tlv_node_state node_state);
242 
243 extern int			 tlv_add_node_info(struct dynar *msg,
244     const struct tlv_node_info *node_info);
245 
246 extern int			 tlv_add_node_list_type(struct dynar *msg,
247     enum tlv_node_list_type node_list_type);
248 
249 extern int			 tlv_add_vote(struct dynar *msg, enum tlv_vote vote);
250 
251 extern int			 tlv_add_quorate(struct dynar *msg, enum tlv_quorate quorate);
252 
253 extern int			 tlv_add_heuristics(struct dynar *msg,
254     enum tlv_heuristics heuristics);
255 
256 extern void			 tlv_iter_init_str(const char *msg, size_t msg_len,
257     size_t msg_header_len, struct tlv_iterator *tlv_iter);
258 
259 extern void			 tlv_iter_init(const struct dynar *msg, size_t msg_header_len,
260     struct tlv_iterator *tlv_iter);
261 
262 extern enum tlv_opt_type	 tlv_iter_get_type(const struct tlv_iterator *tlv_iter);
263 
264 extern uint16_t			 tlv_iter_get_len(const struct tlv_iterator *tlv_iter);
265 
266 extern const char		*tlv_iter_get_data(const struct tlv_iterator *tlv_iter);
267 
268 extern int			 tlv_iter_next(struct tlv_iterator *tlv_iter);
269 
270 extern int			 tlv_iter_decode_u8(struct tlv_iterator *tlv_iter, uint8_t *res);
271 
272 extern int			 tlv_iter_decode_tls_supported(struct tlv_iterator *tlv_iter,
273     enum tlv_tls_supported *tls_supported);
274 
275 extern int			 tlv_iter_decode_u32(struct tlv_iterator *tlv_iter,
276     uint32_t *res);
277 
278 extern int			 tlv_iter_decode_str(struct tlv_iterator *tlv_iter, char **str,
279     size_t *str_len);
280 
281 extern int			 tlv_iter_decode_client_cert_required(
282     struct tlv_iterator *tlv_iter, uint8_t *client_cert_required);
283 
284 extern int			 tlv_iter_decode_u16_array(struct tlv_iterator *tlv_iter,
285     uint16_t **u16a, size_t *no_items);
286 
287 extern int			 tlv_iter_decode_supported_options(struct tlv_iterator *tlv_iter,
288     enum tlv_opt_type **supported_options, size_t *no_supported_options);
289 
290 extern int			 tlv_iter_decode_supported_decision_algorithms(
291     struct tlv_iterator *tlv_iter,
292     enum tlv_decision_algorithm_type **supported_decision_algorithms,
293     size_t *no_supported_decision_algorithms);
294 
295 extern int			 tlv_iter_decode_u16(struct tlv_iterator *tlv_iter,
296     uint16_t *u16);
297 
298 extern int			 tlv_iter_decode_u64(struct tlv_iterator *tlv_iter,
299     uint64_t *u64);
300 
301 extern int			 tlv_iter_decode_reply_error_code(struct tlv_iterator *tlv_iter,
302     enum tlv_reply_error_code *reply_error_code);
303 
304 extern int			 tlv_iter_decode_decision_algorithm(struct tlv_iterator *tlv_iter,
305     enum tlv_decision_algorithm_type *decision_algorithm);
306 
307 extern int			 tlv_iter_decode_ring_id(struct tlv_iterator *tlv_iter,
308     struct tlv_ring_id *ring_id);
309 
310 extern int			 tlv_iter_decode_tie_breaker(struct tlv_iterator *tlv_iter,
311     struct tlv_tie_breaker *tie_breaker);
312 
313 extern int			 tlv_iter_decode_node_state(struct tlv_iterator *tlv_iter,
314     enum tlv_node_state *node_state);
315 
316 extern int			 tlv_iter_decode_node_info(struct tlv_iterator *tlv_iter,
317     struct tlv_node_info *node_info);
318 
319 extern int			 tlv_iter_decode_node_list_type(struct tlv_iterator *tlv_iter,
320     enum tlv_node_list_type *node_list_type);
321 
322 extern int			 tlv_iter_decode_vote(struct tlv_iterator *tlv_iter,
323     enum tlv_vote *vote);
324 
325 extern int			 tlv_iter_decode_quorate(struct tlv_iterator *tlv_iter,
326     enum tlv_quorate *quorate);
327 
328 extern int			 tlv_iter_decode_heuristics(struct tlv_iterator *tlv_iter,
329     enum tlv_heuristics *heuristics);
330 
331 extern void			 tlv_get_supported_options(enum tlv_opt_type **supported_options,
332     size_t *no_supported_options);
333 
334 extern int			 tlv_ring_id_eq(const struct tlv_ring_id *rid1,
335     const struct tlv_ring_id *rid2);
336 
337 extern int			 tlv_tie_breaker_eq(const struct tlv_tie_breaker *tb1,
338     const struct tlv_tie_breaker *tb2);
339 
340 extern const char		*tlv_vote_to_str(enum tlv_vote vote);
341 
342 extern const char		*tlv_node_state_to_str(enum tlv_node_state state);
343 
344 extern const char		*tlv_tls_supported_to_str(enum tlv_tls_supported tls_supported);
345 
346 extern const char		*tlv_decision_algorithm_type_to_str(
347     enum tlv_decision_algorithm_type algorithm);
348 
349 extern const char		*tlv_heuristics_to_str(enum tlv_heuristics heuristics);
350 
351 /*
352  * Compare h1 and h2. Return -1 if h1 < h2, 0 if h1 == h2 and 1 if h1 > h2
353  */
354 extern int			 tlv_heuristics_cmp(enum tlv_heuristics h1, enum tlv_heuristics h2);
355 
356 #ifdef __cplusplus
357 }
358 #endif
359 
360 #endif /* _TLV_H_ */
361