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