msg.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125
  1. /*
  2. * Copyright (c) 2015-2020 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. #include <sys/types.h>
  35. #include <arpa/inet.h>
  36. #include <inttypes.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include "msg.h"
  40. #define MSG_TYPE_LENGTH 2
  41. #define MSG_LENGTH_LENGTH 4
  42. #define MSG_STATIC_SUPPORTED_MESSAGES_SIZE 18
  43. enum msg_type msg_static_supported_messages[MSG_STATIC_SUPPORTED_MESSAGES_SIZE] = {
  44. MSG_TYPE_PREINIT,
  45. MSG_TYPE_PREINIT_REPLY,
  46. MSG_TYPE_STARTTLS,
  47. MSG_TYPE_INIT,
  48. MSG_TYPE_INIT_REPLY,
  49. MSG_TYPE_SERVER_ERROR,
  50. MSG_TYPE_SET_OPTION,
  51. MSG_TYPE_SET_OPTION_REPLY,
  52. MSG_TYPE_ECHO_REQUEST,
  53. MSG_TYPE_ECHO_REPLY,
  54. MSG_TYPE_NODE_LIST,
  55. MSG_TYPE_NODE_LIST_REPLY,
  56. MSG_TYPE_ASK_FOR_VOTE,
  57. MSG_TYPE_ASK_FOR_VOTE_REPLY,
  58. MSG_TYPE_VOTE_INFO,
  59. MSG_TYPE_VOTE_INFO_REPLY,
  60. MSG_TYPE_HEURISTICS_CHANGE,
  61. MSG_TYPE_HEURISTICS_CHANGE_REPLY,
  62. };
  63. size_t
  64. msg_get_header_length(void)
  65. {
  66. return (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH);
  67. }
  68. static void
  69. msg_add_type(struct dynar *msg, enum msg_type type)
  70. {
  71. uint16_t ntype;
  72. ntype = htons((uint16_t)type);
  73. dynar_cat(msg, &ntype, sizeof(ntype));
  74. }
  75. enum msg_type
  76. msg_get_type(const struct dynar *msg)
  77. {
  78. uint16_t ntype;
  79. uint16_t type;
  80. memcpy(&ntype, dynar_data(msg), sizeof(ntype));
  81. type = ntohs(ntype);
  82. return (type);
  83. }
  84. /*
  85. * We don't know size of message before call of this function, so zero is
  86. * added. Real value is set afterwards by msg_set_len.
  87. */
  88. static void
  89. msg_add_len(struct dynar *msg)
  90. {
  91. uint32_t len;
  92. len = 0;
  93. dynar_cat(msg, &len, sizeof(len));
  94. }
  95. static void
  96. msg_set_len(struct dynar *msg, uint32_t len)
  97. {
  98. uint32_t nlen;
  99. nlen = htonl(len);
  100. memcpy(dynar_data(msg) + MSG_TYPE_LENGTH, &nlen, sizeof(nlen));
  101. }
  102. /*
  103. * Used only for echo reply msg. All other messages should use msg_add_type.
  104. */
  105. static void
  106. msg_set_type(struct dynar *msg, enum msg_type type)
  107. {
  108. uint16_t ntype;
  109. ntype = htons((uint16_t)type);
  110. memcpy(dynar_data(msg), &ntype, sizeof(ntype));
  111. }
  112. uint32_t
  113. msg_get_len(const struct dynar *msg)
  114. {
  115. uint32_t nlen;
  116. uint32_t len;
  117. memcpy(&nlen, dynar_data(msg) + MSG_TYPE_LENGTH, sizeof(nlen));
  118. len = ntohl(nlen);
  119. return (len);
  120. }
  121. size_t
  122. msg_create_preinit(struct dynar *msg, const char *cluster_name, int add_msg_seq_number,
  123. uint32_t msg_seq_number)
  124. {
  125. dynar_clean(msg);
  126. msg_add_type(msg, MSG_TYPE_PREINIT);
  127. msg_add_len(msg);
  128. if (add_msg_seq_number) {
  129. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  130. goto small_buf_err;
  131. }
  132. }
  133. if (tlv_add_cluster_name(msg, cluster_name) == -1) {
  134. goto small_buf_err;
  135. }
  136. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  137. return (dynar_size(msg));
  138. small_buf_err:
  139. return (0);
  140. }
  141. size_t
  142. msg_create_preinit_reply(struct dynar *msg, int add_msg_seq_number, uint32_t msg_seq_number,
  143. enum tlv_tls_supported tls_supported, int tls_client_cert_required)
  144. {
  145. dynar_clean(msg);
  146. msg_add_type(msg, MSG_TYPE_PREINIT_REPLY);
  147. msg_add_len(msg);
  148. if (add_msg_seq_number) {
  149. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  150. goto small_buf_err;
  151. }
  152. }
  153. if (tlv_add_tls_supported(msg, tls_supported) == -1) {
  154. goto small_buf_err;
  155. }
  156. if (tlv_add_tls_client_cert_required(msg, tls_client_cert_required) == -1) {
  157. goto small_buf_err;
  158. }
  159. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  160. return (dynar_size(msg));
  161. small_buf_err:
  162. return (0);
  163. }
  164. size_t
  165. msg_create_starttls(struct dynar *msg, int add_msg_seq_number, uint32_t msg_seq_number)
  166. {
  167. dynar_clean(msg);
  168. msg_add_type(msg, MSG_TYPE_STARTTLS);
  169. msg_add_len(msg);
  170. if (add_msg_seq_number) {
  171. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  172. goto small_buf_err;
  173. }
  174. }
  175. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  176. return (dynar_size(msg));
  177. small_buf_err:
  178. return (0);
  179. }
  180. size_t
  181. msg_create_server_error(struct dynar *msg, int add_msg_seq_number, uint32_t msg_seq_number,
  182. enum tlv_reply_error_code reply_error_code)
  183. {
  184. dynar_clean(msg);
  185. msg_add_type(msg, MSG_TYPE_SERVER_ERROR);
  186. msg_add_len(msg);
  187. if (add_msg_seq_number) {
  188. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  189. goto small_buf_err;
  190. }
  191. }
  192. if (tlv_add_reply_error_code(msg, reply_error_code) == -1) {
  193. goto small_buf_err;
  194. }
  195. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  196. return (dynar_size(msg));
  197. small_buf_err:
  198. return (0);
  199. }
  200. static uint16_t *
  201. msg_convert_msg_type_array_to_u16_array(const enum msg_type *msg_type_array, size_t array_size)
  202. {
  203. uint16_t *u16a;
  204. size_t i;
  205. u16a = malloc(sizeof(*u16a) * array_size);
  206. if (u16a == NULL) {
  207. return (NULL);
  208. }
  209. for (i = 0; i < array_size; i++) {
  210. u16a[i] = (uint16_t)msg_type_array[i];
  211. }
  212. return (u16a);
  213. }
  214. size_t
  215. msg_create_init(struct dynar *msg, int add_msg_seq_number, uint32_t msg_seq_number,
  216. enum tlv_decision_algorithm_type decision_algorithm,
  217. const enum msg_type *supported_msgs, size_t no_supported_msgs,
  218. const enum tlv_opt_type *supported_opts, size_t no_supported_opts, uint32_t node_id,
  219. uint32_t heartbeat_interval, const struct tlv_tie_breaker *tie_breaker,
  220. const struct tlv_ring_id *ring_id)
  221. {
  222. uint16_t *u16a;
  223. int res;
  224. u16a = NULL;
  225. dynar_clean(msg);
  226. msg_add_type(msg, MSG_TYPE_INIT);
  227. msg_add_len(msg);
  228. if (add_msg_seq_number) {
  229. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  230. goto small_buf_err;
  231. }
  232. }
  233. if (supported_msgs != NULL && no_supported_msgs > 0) {
  234. u16a = msg_convert_msg_type_array_to_u16_array(supported_msgs, no_supported_msgs);
  235. if (u16a == NULL) {
  236. goto small_buf_err;
  237. }
  238. res = tlv_add_u16_array(msg, TLV_OPT_SUPPORTED_MESSAGES, u16a, no_supported_msgs);
  239. free(u16a);
  240. if (res == -1) {
  241. goto small_buf_err;
  242. }
  243. }
  244. if (supported_opts != NULL && no_supported_opts > 0) {
  245. if (tlv_add_supported_options(msg, supported_opts, no_supported_opts) == -1) {
  246. goto small_buf_err;
  247. }
  248. }
  249. if (tlv_add_node_id(msg, node_id) == -1) {
  250. goto small_buf_err;
  251. }
  252. if (tlv_add_decision_algorithm(msg, decision_algorithm) == -1) {
  253. goto small_buf_err;
  254. }
  255. if (tlv_add_heartbeat_interval(msg, heartbeat_interval) == -1) {
  256. goto small_buf_err;
  257. }
  258. if (tlv_add_tie_breaker(msg, tie_breaker) == -1) {
  259. goto small_buf_err;
  260. }
  261. if (tlv_add_ring_id(msg, ring_id) == -1) {
  262. goto small_buf_err;
  263. }
  264. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  265. return (dynar_size(msg));
  266. small_buf_err:
  267. return (0);
  268. }
  269. size_t
  270. msg_create_init_reply(struct dynar *msg, int add_msg_seq_number, uint32_t msg_seq_number,
  271. enum tlv_reply_error_code reply_error_code,
  272. const enum msg_type *supported_msgs, size_t no_supported_msgs,
  273. const enum tlv_opt_type *supported_opts, size_t no_supported_opts,
  274. size_t server_maximum_request_size, size_t server_maximum_reply_size,
  275. const enum tlv_decision_algorithm_type *supported_decision_algorithms,
  276. size_t no_supported_decision_algorithms)
  277. {
  278. uint16_t *u16a;
  279. int res;
  280. u16a = NULL;
  281. dynar_clean(msg);
  282. msg_add_type(msg, MSG_TYPE_INIT_REPLY);
  283. msg_add_len(msg);
  284. if (tlv_add_reply_error_code(msg, reply_error_code) == -1) {
  285. goto small_buf_err;
  286. }
  287. if (supported_msgs != NULL && no_supported_msgs > 0) {
  288. u16a = msg_convert_msg_type_array_to_u16_array(supported_msgs, no_supported_msgs);
  289. if (u16a == NULL) {
  290. goto small_buf_err;
  291. }
  292. res = tlv_add_u16_array(msg, TLV_OPT_SUPPORTED_MESSAGES, u16a, no_supported_msgs);
  293. free(u16a);
  294. if (res == -1) {
  295. goto small_buf_err;
  296. }
  297. }
  298. if (supported_opts != NULL && no_supported_opts > 0) {
  299. if (tlv_add_supported_options(msg, supported_opts, no_supported_opts) == -1) {
  300. goto small_buf_err;
  301. }
  302. }
  303. if (add_msg_seq_number) {
  304. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  305. goto small_buf_err;
  306. }
  307. }
  308. if (tlv_add_server_maximum_request_size(msg, server_maximum_request_size) == -1) {
  309. goto small_buf_err;
  310. }
  311. if (tlv_add_server_maximum_reply_size(msg, server_maximum_reply_size) == -1) {
  312. goto small_buf_err;
  313. }
  314. if (supported_decision_algorithms != NULL && no_supported_decision_algorithms > 0) {
  315. if (tlv_add_supported_decision_algorithms(msg, supported_decision_algorithms,
  316. no_supported_decision_algorithms) == -1) {
  317. goto small_buf_err;
  318. }
  319. }
  320. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  321. return (dynar_size(msg));
  322. small_buf_err:
  323. return (0);
  324. }
  325. size_t
  326. msg_create_set_option(struct dynar *msg, int add_msg_seq_number, uint32_t msg_seq_number,
  327. int add_heartbeat_interval, uint32_t heartbeat_interval,
  328. int add_keep_active_partition_tie_breaker,
  329. enum tlv_keep_active_partition_tie_breaker keep_active_partiton_tie_breaker)
  330. {
  331. dynar_clean(msg);
  332. msg_add_type(msg, MSG_TYPE_SET_OPTION);
  333. msg_add_len(msg);
  334. if (add_msg_seq_number) {
  335. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  336. goto small_buf_err;
  337. }
  338. }
  339. if (add_heartbeat_interval) {
  340. if (tlv_add_heartbeat_interval(msg, heartbeat_interval) == -1) {
  341. goto small_buf_err;
  342. }
  343. }
  344. if (add_keep_active_partition_tie_breaker) {
  345. if (tlv_add_keep_active_partition_tie_breaker(msg,
  346. keep_active_partiton_tie_breaker) == -1) {
  347. goto small_buf_err;
  348. }
  349. }
  350. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  351. return (dynar_size(msg));
  352. small_buf_err:
  353. return (0);
  354. }
  355. size_t
  356. msg_create_set_option_reply(struct dynar *msg, int add_msg_seq_number, uint32_t msg_seq_number,
  357. int add_heartbeat_interval, uint32_t heartbeat_interval,
  358. int add_keep_active_partition_tie_breaker,
  359. enum tlv_keep_active_partition_tie_breaker keep_active_partiton_tie_breaker)
  360. {
  361. dynar_clean(msg);
  362. msg_add_type(msg, MSG_TYPE_SET_OPTION_REPLY);
  363. msg_add_len(msg);
  364. if (add_msg_seq_number) {
  365. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  366. goto small_buf_err;
  367. }
  368. }
  369. if (add_heartbeat_interval) {
  370. if (tlv_add_heartbeat_interval(msg, heartbeat_interval) == -1) {
  371. goto small_buf_err;
  372. }
  373. }
  374. if (add_keep_active_partition_tie_breaker) {
  375. if (tlv_add_keep_active_partition_tie_breaker(msg,
  376. keep_active_partiton_tie_breaker) == -1) {
  377. goto small_buf_err;
  378. }
  379. }
  380. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  381. return (dynar_size(msg));
  382. small_buf_err:
  383. return (0);
  384. }
  385. size_t
  386. msg_create_echo_request(struct dynar *msg, int add_msg_seq_number, uint32_t msg_seq_number)
  387. {
  388. dynar_clean(msg);
  389. msg_add_type(msg, MSG_TYPE_ECHO_REQUEST);
  390. msg_add_len(msg);
  391. if (add_msg_seq_number) {
  392. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  393. goto small_buf_err;
  394. }
  395. }
  396. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  397. return (dynar_size(msg));
  398. small_buf_err:
  399. return (0);
  400. }
  401. size_t
  402. msg_create_echo_reply(struct dynar *msg, const struct dynar *echo_request_msg)
  403. {
  404. dynar_clean(msg);
  405. if (dynar_cat(msg, dynar_data(echo_request_msg), dynar_size(echo_request_msg)) == -1) {
  406. goto small_buf_err;
  407. }
  408. msg_set_type(msg, MSG_TYPE_ECHO_REPLY);
  409. return (dynar_size(msg));
  410. small_buf_err:
  411. return (0);
  412. }
  413. size_t
  414. msg_create_node_list(struct dynar *msg,
  415. uint32_t msg_seq_number, enum tlv_node_list_type node_list_type,
  416. int add_ring_id, const struct tlv_ring_id *ring_id,
  417. int add_config_version, uint64_t config_version,
  418. int add_quorate, enum tlv_quorate quorate,
  419. int add_heuristics, enum tlv_heuristics heuristics,
  420. const struct node_list *nodes)
  421. {
  422. struct node_list_entry *node_info;
  423. struct tlv_node_info tlv_ni;
  424. dynar_clean(msg);
  425. msg_add_type(msg, MSG_TYPE_NODE_LIST);
  426. msg_add_len(msg);
  427. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  428. goto small_buf_err;
  429. }
  430. if (tlv_add_node_list_type(msg, node_list_type) == -1) {
  431. goto small_buf_err;
  432. }
  433. if (add_ring_id) {
  434. if (tlv_add_ring_id(msg, ring_id) == -1) {
  435. goto small_buf_err;
  436. }
  437. }
  438. if (add_config_version) {
  439. if (tlv_add_config_version(msg, config_version) == -1) {
  440. goto small_buf_err;
  441. }
  442. }
  443. if (add_quorate) {
  444. if (tlv_add_quorate(msg, quorate) == -1) {
  445. goto small_buf_err;
  446. }
  447. }
  448. TAILQ_FOREACH(node_info, nodes, entries) {
  449. node_list_entry_to_tlv_node_info(node_info, &tlv_ni);
  450. if (tlv_add_node_info(msg, &tlv_ni) == -1) {
  451. goto small_buf_err;
  452. }
  453. }
  454. if (add_heuristics && heuristics != TLV_HEURISTICS_UNDEFINED) {
  455. if (tlv_add_heuristics(msg, heuristics) == -1) {
  456. goto small_buf_err;
  457. }
  458. }
  459. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  460. return (dynar_size(msg));
  461. small_buf_err:
  462. return (0);
  463. }
  464. size_t
  465. msg_create_node_list_reply(struct dynar *msg, uint32_t msg_seq_number,
  466. enum tlv_node_list_type node_list_type, const struct tlv_ring_id *ring_id,
  467. enum tlv_vote vote)
  468. {
  469. dynar_clean(msg);
  470. msg_add_type(msg, MSG_TYPE_NODE_LIST_REPLY);
  471. msg_add_len(msg);
  472. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  473. goto small_buf_err;
  474. }
  475. if (tlv_add_node_list_type(msg, node_list_type) == -1) {
  476. goto small_buf_err;
  477. }
  478. if (tlv_add_ring_id(msg, ring_id) == -1) {
  479. goto small_buf_err;
  480. }
  481. if (tlv_add_vote(msg, vote) == -1) {
  482. goto small_buf_err;
  483. }
  484. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  485. return (dynar_size(msg));
  486. small_buf_err:
  487. return (0);
  488. }
  489. size_t
  490. msg_create_ask_for_vote(struct dynar *msg, uint32_t msg_seq_number)
  491. {
  492. dynar_clean(msg);
  493. msg_add_type(msg, MSG_TYPE_ASK_FOR_VOTE);
  494. msg_add_len(msg);
  495. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  496. goto small_buf_err;
  497. }
  498. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  499. return (dynar_size(msg));
  500. small_buf_err:
  501. return (0);
  502. }
  503. size_t
  504. msg_create_ask_for_vote_reply(struct dynar *msg, uint32_t msg_seq_number,
  505. const struct tlv_ring_id *ring_id, enum tlv_vote vote)
  506. {
  507. dynar_clean(msg);
  508. msg_add_type(msg, MSG_TYPE_ASK_FOR_VOTE_REPLY);
  509. msg_add_len(msg);
  510. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  511. goto small_buf_err;
  512. }
  513. if (tlv_add_vote(msg, vote) == -1) {
  514. goto small_buf_err;
  515. }
  516. if (tlv_add_ring_id(msg, ring_id) == -1) {
  517. goto small_buf_err;
  518. }
  519. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  520. return (dynar_size(msg));
  521. small_buf_err:
  522. return (0);
  523. }
  524. size_t
  525. msg_create_vote_info(struct dynar *msg, uint32_t msg_seq_number, const struct tlv_ring_id *ring_id,
  526. enum tlv_vote vote)
  527. {
  528. dynar_clean(msg);
  529. msg_add_type(msg, MSG_TYPE_VOTE_INFO);
  530. msg_add_len(msg);
  531. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  532. goto small_buf_err;
  533. }
  534. if (tlv_add_vote(msg, vote) == -1) {
  535. goto small_buf_err;
  536. }
  537. if (tlv_add_ring_id(msg, ring_id) == -1) {
  538. goto small_buf_err;
  539. }
  540. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  541. return (dynar_size(msg));
  542. small_buf_err:
  543. return (0);
  544. }
  545. size_t
  546. msg_create_vote_info_reply(struct dynar *msg, uint32_t msg_seq_number)
  547. {
  548. dynar_clean(msg);
  549. msg_add_type(msg, MSG_TYPE_VOTE_INFO_REPLY);
  550. msg_add_len(msg);
  551. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  552. goto small_buf_err;
  553. }
  554. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  555. return (dynar_size(msg));
  556. small_buf_err:
  557. return (0);
  558. }
  559. size_t
  560. msg_create_heuristics_change(struct dynar *msg, uint32_t msg_seq_number,
  561. enum tlv_heuristics heuristics)
  562. {
  563. dynar_clean(msg);
  564. msg_add_type(msg, MSG_TYPE_HEURISTICS_CHANGE);
  565. msg_add_len(msg);
  566. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  567. goto small_buf_err;
  568. }
  569. if (tlv_add_heuristics(msg, heuristics) == -1) {
  570. goto small_buf_err;
  571. }
  572. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  573. return (dynar_size(msg));
  574. small_buf_err:
  575. return (0);
  576. }
  577. size_t
  578. msg_create_heuristics_change_reply(struct dynar *msg, uint32_t msg_seq_number,
  579. const struct tlv_ring_id *ring_id, enum tlv_heuristics heuristics, enum tlv_vote vote)
  580. {
  581. dynar_clean(msg);
  582. msg_add_type(msg, MSG_TYPE_HEURISTICS_CHANGE_REPLY);
  583. msg_add_len(msg);
  584. if (tlv_add_msg_seq_number(msg, msg_seq_number) == -1) {
  585. goto small_buf_err;
  586. }
  587. if (tlv_add_vote(msg, vote) == -1) {
  588. goto small_buf_err;
  589. }
  590. if (tlv_add_ring_id(msg, ring_id) == -1) {
  591. goto small_buf_err;
  592. }
  593. if (tlv_add_heuristics(msg, heuristics) == -1) {
  594. goto small_buf_err;
  595. }
  596. msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
  597. return (dynar_size(msg));
  598. small_buf_err:
  599. return (0);
  600. }
  601. int
  602. msg_is_valid_msg_type(const struct dynar *msg)
  603. {
  604. enum msg_type type;
  605. size_t i;
  606. type = msg_get_type(msg);
  607. for (i = 0; i < MSG_STATIC_SUPPORTED_MESSAGES_SIZE; i++) {
  608. if (msg_static_supported_messages[i] == type) {
  609. return (1);
  610. }
  611. }
  612. return (0);
  613. }
  614. void
  615. msg_decoded_init(struct msg_decoded *decoded_msg)
  616. {
  617. memset(decoded_msg, 0, sizeof(*decoded_msg));
  618. node_list_init(&decoded_msg->nodes);
  619. }
  620. void
  621. msg_decoded_destroy(struct msg_decoded *decoded_msg)
  622. {
  623. free(decoded_msg->cluster_name);
  624. free(decoded_msg->supported_messages);
  625. free(decoded_msg->supported_options);
  626. free(decoded_msg->supported_decision_algorithms);
  627. node_list_free(&decoded_msg->nodes);
  628. msg_decoded_init(decoded_msg);
  629. }
  630. /*
  631. * 0 - No error
  632. * -1 - option with invalid length
  633. * -2 - Unable to allocate memory
  634. * -3 - Inconsistent msg (tlv len > msg size)
  635. * -4 - invalid option content
  636. */
  637. int
  638. msg_decode(const struct dynar *msg, struct msg_decoded *decoded_msg)
  639. {
  640. struct tlv_iterator tlv_iter;
  641. uint16_t *u16a;
  642. uint32_t u32;
  643. uint64_t u64;
  644. struct tlv_ring_id ring_id;
  645. struct tlv_node_info node_info;
  646. struct tlv_tie_breaker tie_breaker;
  647. size_t zi;
  648. enum tlv_opt_type opt_type;
  649. int iter_res;
  650. int res;
  651. enum tlv_keep_active_partition_tie_breaker keep_active_partition_tb;
  652. msg_decoded_destroy(decoded_msg);
  653. decoded_msg->type = msg_get_type(msg);
  654. tlv_iter_init(msg, msg_get_header_length(), &tlv_iter);
  655. while ((iter_res = tlv_iter_next(&tlv_iter)) > 0) {
  656. opt_type = tlv_iter_get_type(&tlv_iter);
  657. switch (opt_type) {
  658. case TLV_OPT_MSG_SEQ_NUMBER:
  659. if ((res = tlv_iter_decode_u32(&tlv_iter, &u32)) != 0) {
  660. return (res);
  661. }
  662. decoded_msg->seq_number_set = 1;
  663. decoded_msg->seq_number = u32;
  664. break;
  665. case TLV_OPT_CLUSTER_NAME:
  666. if ((res = tlv_iter_decode_str(&tlv_iter, &decoded_msg->cluster_name,
  667. &decoded_msg->cluster_name_len)) != 0) {
  668. return (-2);
  669. }
  670. break;
  671. case TLV_OPT_TLS_SUPPORTED:
  672. if ((res = tlv_iter_decode_tls_supported(&tlv_iter,
  673. &decoded_msg->tls_supported)) != 0) {
  674. return (res);
  675. }
  676. decoded_msg->tls_supported_set = 1;
  677. break;
  678. case TLV_OPT_TLS_CLIENT_CERT_REQUIRED:
  679. if ((res = tlv_iter_decode_client_cert_required(&tlv_iter,
  680. &decoded_msg->tls_client_cert_required)) != 0) {
  681. return (res);
  682. }
  683. decoded_msg->tls_client_cert_required_set = 1;
  684. break;
  685. case TLV_OPT_SUPPORTED_MESSAGES:
  686. free(decoded_msg->supported_messages);
  687. if ((res = tlv_iter_decode_u16_array(&tlv_iter, &u16a,
  688. &decoded_msg->no_supported_messages)) != 0) {
  689. return (res);
  690. }
  691. decoded_msg->supported_messages =
  692. malloc(sizeof(enum msg_type) * decoded_msg->no_supported_messages);
  693. if (decoded_msg->supported_messages == NULL) {
  694. free(u16a);
  695. return (-2);
  696. }
  697. for (zi = 0; zi < decoded_msg->no_supported_messages; zi++) {
  698. decoded_msg->supported_messages[zi] = (enum msg_type)u16a[zi];
  699. }
  700. free(u16a);
  701. break;
  702. case TLV_OPT_SUPPORTED_OPTIONS:
  703. free(decoded_msg->supported_options);
  704. if ((res = tlv_iter_decode_supported_options(&tlv_iter,
  705. &decoded_msg->supported_options,
  706. &decoded_msg->no_supported_options)) != 0) {
  707. return (res);
  708. }
  709. break;
  710. case TLV_OPT_REPLY_ERROR_CODE:
  711. if ((res = tlv_iter_decode_reply_error_code(&tlv_iter,
  712. &decoded_msg->reply_error_code)) != 0) {
  713. return (res);
  714. }
  715. decoded_msg->reply_error_code_set = 1;
  716. break;
  717. case TLV_OPT_SERVER_MAXIMUM_REQUEST_SIZE:
  718. if ((res = tlv_iter_decode_u32(&tlv_iter, &u32)) != 0) {
  719. return (res);
  720. }
  721. decoded_msg->server_maximum_request_size_set = 1;
  722. decoded_msg->server_maximum_request_size = u32;
  723. break;
  724. case TLV_OPT_SERVER_MAXIMUM_REPLY_SIZE:
  725. if ((res = tlv_iter_decode_u32(&tlv_iter, &u32)) != 0) {
  726. return (res);
  727. }
  728. decoded_msg->server_maximum_reply_size_set = 1;
  729. decoded_msg->server_maximum_reply_size = u32;
  730. break;
  731. case TLV_OPT_NODE_ID:
  732. if ((res = tlv_iter_decode_u32(&tlv_iter, &u32)) != 0) {
  733. return (res);
  734. }
  735. decoded_msg->node_id_set = 1;
  736. decoded_msg->node_id = u32;
  737. break;
  738. case TLV_OPT_SUPPORTED_DECISION_ALGORITHMS:
  739. free(decoded_msg->supported_decision_algorithms);
  740. if ((res = tlv_iter_decode_supported_decision_algorithms(&tlv_iter,
  741. &decoded_msg->supported_decision_algorithms,
  742. &decoded_msg->no_supported_decision_algorithms)) != 0) {
  743. return (res);
  744. }
  745. break;
  746. case TLV_OPT_DECISION_ALGORITHM:
  747. if ((res = tlv_iter_decode_decision_algorithm(&tlv_iter,
  748. &decoded_msg->decision_algorithm)) != 0) {
  749. return (res);
  750. }
  751. decoded_msg->decision_algorithm_set = 1;
  752. break;
  753. case TLV_OPT_HEARTBEAT_INTERVAL:
  754. if ((res = tlv_iter_decode_u32(&tlv_iter, &u32)) != 0) {
  755. return (res);
  756. }
  757. decoded_msg->heartbeat_interval_set = 1;
  758. decoded_msg->heartbeat_interval = u32;
  759. break;
  760. case TLV_OPT_RING_ID:
  761. if ((res = tlv_iter_decode_ring_id(&tlv_iter, &ring_id)) != 0) {
  762. return (res);
  763. }
  764. decoded_msg->ring_id_set = 1;
  765. memcpy(&decoded_msg->ring_id, &ring_id, sizeof(ring_id));
  766. break;
  767. case TLV_OPT_CONFIG_VERSION:
  768. if ((res = tlv_iter_decode_u64(&tlv_iter, &u64)) != 0) {
  769. return (res);
  770. }
  771. decoded_msg->config_version_set = 1;
  772. decoded_msg->config_version = u64;
  773. break;
  774. case TLV_OPT_DATA_CENTER_ID:
  775. if ((res = tlv_iter_decode_u32(&tlv_iter, &u32)) != 0) {
  776. return (res);
  777. }
  778. decoded_msg->data_center_id = u32;
  779. break;
  780. case TLV_OPT_NODE_STATE:
  781. if ((res = tlv_iter_decode_node_state(&tlv_iter,
  782. &decoded_msg->node_state)) != 0) {
  783. return (res);
  784. }
  785. break;
  786. case TLV_OPT_NODE_INFO:
  787. if ((res = tlv_iter_decode_node_info(&tlv_iter, &node_info)) != 0) {
  788. return (res);
  789. }
  790. if (node_list_add_from_node_info(&decoded_msg->nodes, &node_info) == NULL) {
  791. return (-2);
  792. }
  793. break;
  794. case TLV_OPT_NODE_LIST_TYPE:
  795. if ((res = tlv_iter_decode_node_list_type(&tlv_iter,
  796. &decoded_msg->node_list_type)) != 0) {
  797. return (res);
  798. }
  799. decoded_msg->node_list_type_set = 1;
  800. break;
  801. case TLV_OPT_VOTE:
  802. if ((res = tlv_iter_decode_vote(&tlv_iter, &decoded_msg->vote)) != 0) {
  803. return (res);
  804. }
  805. decoded_msg->vote_set = 1;
  806. break;
  807. case TLV_OPT_QUORATE:
  808. if ((res = tlv_iter_decode_quorate(&tlv_iter,
  809. &decoded_msg->quorate)) != 0) {
  810. return (res);
  811. }
  812. decoded_msg->quorate_set = 1;
  813. break;
  814. case TLV_OPT_TIE_BREAKER:
  815. if ((res = tlv_iter_decode_tie_breaker(&tlv_iter, &tie_breaker)) != 0) {
  816. return (res);
  817. }
  818. decoded_msg->tie_breaker_set = 1;
  819. memcpy(&decoded_msg->tie_breaker, &tie_breaker, sizeof(tie_breaker));
  820. break;
  821. case TLV_OPT_HEURISTICS:
  822. if ((res = tlv_iter_decode_heuristics(&tlv_iter,
  823. &decoded_msg->heuristics)) != 0) {
  824. return (res);
  825. }
  826. break;
  827. case TLV_OPT_KEEP_ACTIVE_PARTITION_TIE_BREAKER:
  828. if ((res = tlv_iter_decode_keep_active_partition_tie_breaker(&tlv_iter,
  829. &keep_active_partition_tb)) != 0) {
  830. return (res);
  831. }
  832. decoded_msg->keep_active_partition_tie_breaker_set = 1;
  833. decoded_msg->keep_active_partition_tie_breaker = keep_active_partition_tb;
  834. break;
  835. /*
  836. * Default is not defined intentionally. Compiler shows warning when
  837. * new tlv option is added. Also protocol ignores unknown options so
  838. * no extra work is needed.
  839. */
  840. }
  841. }
  842. if (iter_res != 0) {
  843. return (-3);
  844. }
  845. return (0);
  846. }
  847. void
  848. msg_get_supported_messages(enum msg_type **supported_messages, size_t *no_supported_messages)
  849. {
  850. *supported_messages = msg_static_supported_messages;
  851. *no_supported_messages = MSG_STATIC_SUPPORTED_MESSAGES_SIZE;
  852. }
  853. const char *
  854. msg_type_to_str(enum msg_type type)
  855. {
  856. switch (type) {
  857. case MSG_TYPE_PREINIT: return ("Preinit"); break;
  858. case MSG_TYPE_PREINIT_REPLY: return ("Preinit reply"); break;
  859. case MSG_TYPE_STARTTLS: return ("StartTLS"); break;
  860. case MSG_TYPE_INIT: return ("Init"); break;
  861. case MSG_TYPE_INIT_REPLY: return ("Init reply"); break;
  862. case MSG_TYPE_SERVER_ERROR: return ("Server error"); break;
  863. case MSG_TYPE_SET_OPTION: return ("Set option"); break;
  864. case MSG_TYPE_SET_OPTION_REPLY: return ("Set option reply"); break;
  865. case MSG_TYPE_ECHO_REQUEST: return ("Echo request"); break;
  866. case MSG_TYPE_ECHO_REPLY: return ("Echo reply"); break;
  867. case MSG_TYPE_NODE_LIST: return ("Node list"); break;
  868. case MSG_TYPE_NODE_LIST_REPLY: return ("Node list reply"); break;
  869. case MSG_TYPE_ASK_FOR_VOTE: return ("Ask for vote"); break;
  870. case MSG_TYPE_ASK_FOR_VOTE_REPLY: return ("Ask for vote reply"); break;
  871. case MSG_TYPE_VOTE_INFO: return ("Vote info"); break;
  872. case MSG_TYPE_VOTE_INFO_REPLY: return ("Vote info reply"); break;
  873. case MSG_TYPE_HEURISTICS_CHANGE: return ("Heuristics change"); break;
  874. case MSG_TYPE_HEURISTICS_CHANGE_REPLY: return ("Heuristics change reply"); break;
  875. }
  876. return ("Unknown message type");
  877. }