qnetd-client-msg-received.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  1. /*
  2. * Copyright (c) 2015-2016 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 "qnetd-algorithm.h"
  36. #include "qnetd-instance.h"
  37. #include "qnetd-log.h"
  38. #include "qnetd-log-debug.h"
  39. #include "qnetd-client-send.h"
  40. #include "msg.h"
  41. #include "nss-sock.h"
  42. #include "qnetd-client-msg-received.h"
  43. /*
  44. * 0 - Success
  45. * -1 - Disconnect client
  46. * -2 - Error reply sent, but no need to disconnect client
  47. */
  48. static int
  49. qnetd_client_msg_received_check_tls(struct qnetd_instance *instance, struct qnetd_client *client,
  50. const struct msg_decoded *msg)
  51. {
  52. int check_certificate;
  53. int tls_required;
  54. CERTCertificate *peer_cert;
  55. check_certificate = 0;
  56. tls_required = 0;
  57. switch (instance->tls_supported) {
  58. case TLV_TLS_UNSUPPORTED:
  59. tls_required = 0;
  60. check_certificate = 0;
  61. break;
  62. case TLV_TLS_SUPPORTED:
  63. tls_required = 0;
  64. if (client->tls_started && instance->tls_client_cert_required &&
  65. !client->tls_peer_certificate_verified) {
  66. check_certificate = 1;
  67. }
  68. break;
  69. case TLV_TLS_REQUIRED:
  70. tls_required = 1;
  71. if (instance->tls_client_cert_required && !client->tls_peer_certificate_verified) {
  72. check_certificate = 1;
  73. }
  74. break;
  75. default:
  76. qnetd_log(LOG_ERR, "Unhandled instance tls supported %u", instance->tls_supported);
  77. exit(1);
  78. break;
  79. }
  80. if (tls_required && !client->tls_started) {
  81. qnetd_log(LOG_ERR, "TLS is required but doesn't started yet. "
  82. "Sending back error message");
  83. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  84. TLV_REPLY_ERROR_CODE_TLS_REQUIRED) != 0) {
  85. return (-1);
  86. }
  87. return (-2);
  88. }
  89. if (check_certificate) {
  90. peer_cert = SSL_PeerCertificate(client->socket);
  91. if (peer_cert == NULL) {
  92. qnetd_log(LOG_ERR, "Client doesn't sent valid certificate. "
  93. "Disconnecting client");
  94. return (-1);
  95. }
  96. if (CERT_VerifyCertName(peer_cert, client->cluster_name) != SECSuccess) {
  97. qnetd_log(LOG_ERR, "Client doesn't sent certificate with valid CN. "
  98. "Disconnecting client");
  99. CERT_DestroyCertificate(peer_cert);
  100. return (-1);
  101. }
  102. CERT_DestroyCertificate(peer_cert);
  103. client->tls_peer_certificate_verified = 1;
  104. }
  105. return (0);
  106. }
  107. static int
  108. qnetd_client_msg_received_preinit(struct qnetd_instance *instance, struct qnetd_client *client,
  109. const struct msg_decoded *msg)
  110. {
  111. struct send_buffer_list_entry *send_buffer;
  112. if (msg->cluster_name == NULL) {
  113. qnetd_log(LOG_ERR, "Received preinit message without cluster name. "
  114. "Sending error reply.");
  115. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  116. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  117. return (-1);
  118. }
  119. return (0);
  120. }
  121. client->cluster_name = malloc(msg->cluster_name_len + 1);
  122. if (client->cluster_name == NULL) {
  123. qnetd_log(LOG_ERR, "Can't allocate cluster name. Sending error reply.");
  124. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  125. TLV_REPLY_ERROR_CODE_INTERNAL_ERROR) != 0) {
  126. return (-1);
  127. }
  128. return (0);
  129. }
  130. memset(client->cluster_name, 0, msg->cluster_name_len + 1);
  131. memcpy(client->cluster_name, msg->cluster_name, msg->cluster_name_len);
  132. client->cluster_name_len = msg->cluster_name_len;
  133. client->preinit_received = 1;
  134. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  135. if (send_buffer == NULL) {
  136. qnetd_log(LOG_ERR, "Can't alloc preinit reply msg from list. "
  137. "Disconnecting client connection.");
  138. return (-1);
  139. }
  140. if (msg_create_preinit_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  141. instance->tls_supported, instance->tls_client_cert_required) == 0) {
  142. qnetd_log(LOG_ERR, "Can't alloc preinit reply msg. "
  143. "Disconnecting client connection.");
  144. return (-1);
  145. };
  146. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  147. return (0);
  148. }
  149. static int
  150. qnetd_client_msg_received_unexpected_msg(struct qnetd_client *client,
  151. const struct msg_decoded *msg, const char *msg_str)
  152. {
  153. qnetd_log(LOG_ERR, "Received %s message. Sending back error message", msg_str);
  154. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  155. TLV_REPLY_ERROR_CODE_UNEXPECTED_MESSAGE) != 0) {
  156. return (-1);
  157. }
  158. return (0);
  159. }
  160. static int
  161. qnetd_client_msg_received_preinit_reply(struct qnetd_instance *instance,
  162. struct qnetd_client *client, const struct msg_decoded *msg)
  163. {
  164. return (qnetd_client_msg_received_unexpected_msg(client, msg, "preinit reply"));
  165. }
  166. static int
  167. qnetd_client_msg_received_starttls(struct qnetd_instance *instance, struct qnetd_client *client,
  168. const struct msg_decoded *msg)
  169. {
  170. PRFileDesc *new_pr_fd;
  171. if (!client->preinit_received) {
  172. qnetd_log(LOG_ERR, "Received starttls before preinit message. "
  173. "Sending error reply.");
  174. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  175. TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED) != 0) {
  176. return (-1);
  177. }
  178. return (0);
  179. }
  180. if ((new_pr_fd = nss_sock_start_ssl_as_server(client->socket, instance->server.cert,
  181. instance->server.private_key, instance->tls_client_cert_required, 0, NULL)) == NULL) {
  182. qnetd_log_nss(LOG_ERR, "Can't start TLS. Disconnecting client.");
  183. return (-1);
  184. }
  185. client->tls_started = 1;
  186. client->tls_peer_certificate_verified = 0;
  187. client->socket = new_pr_fd;
  188. return (0);
  189. }
  190. static int
  191. qnetd_client_msg_received_server_error(struct qnetd_instance *instance, struct qnetd_client *client,
  192. const struct msg_decoded *msg)
  193. {
  194. return (qnetd_client_msg_received_unexpected_msg(client, msg, "server error"));
  195. }
  196. static int
  197. qnetd_client_msg_received_init(struct qnetd_instance *instance, struct qnetd_client *client,
  198. const struct msg_decoded *msg)
  199. {
  200. int res;
  201. size_t zi;
  202. enum msg_type *supported_msgs;
  203. size_t no_supported_msgs;
  204. enum tlv_opt_type *supported_opts;
  205. size_t no_supported_opts;
  206. struct send_buffer_list_entry *send_buffer;
  207. enum tlv_reply_error_code reply_error_code;
  208. struct qnetd_cluster *cluster;
  209. supported_msgs = NULL;
  210. supported_opts = NULL;
  211. no_supported_msgs = 0;
  212. no_supported_opts = 0;
  213. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  214. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  215. return (res == -1 ? -1 : 0);
  216. }
  217. if (!client->preinit_received) {
  218. qnetd_log(LOG_ERR, "Received init before preinit message. Sending error reply.");
  219. reply_error_code = TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED;
  220. }
  221. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->node_id_set) {
  222. qnetd_log(LOG_ERR, "Received init message without node id set. "
  223. "Sending error reply.");
  224. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  225. } else {
  226. client->node_id_set = 1;
  227. client->node_id = msg->node_id;
  228. }
  229. if (msg->supported_messages != NULL) {
  230. /*
  231. * Client sent supported messages. For now this is ignored but in the future
  232. * this may be used to ensure backward compatibility.
  233. */
  234. /*
  235. for (i = 0; i < msg->no_supported_messages; i++) {
  236. qnetd_log(LOG_DEBUG, "Client supports %u message",
  237. (int)msg->supported_messages[i]);
  238. }
  239. */
  240. /*
  241. * Sent back supported messages
  242. */
  243. msg_get_supported_messages(&supported_msgs, &no_supported_msgs);
  244. }
  245. if (msg->supported_options != NULL) {
  246. /*
  247. * Client sent supported options. For now this is ignored but in the future
  248. * this may be used to ensure backward compatibility.
  249. */
  250. /*
  251. for (i = 0; i < msg->no_supported_options; i++) {
  252. qnetd_log(LOG_DEBUG, "Client supports %u option",
  253. (int)msg->supported_messages[i]);
  254. }
  255. */
  256. /*
  257. * Send back supported options
  258. */
  259. tlv_get_supported_options(&supported_opts, &no_supported_opts);
  260. }
  261. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->decision_algorithm_set) {
  262. qnetd_log(LOG_ERR, "Received init message without decision algorithm. "
  263. "Sending error reply.");
  264. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  265. } else {
  266. /*
  267. * Check if decision algorithm requested by client is supported
  268. */
  269. res = 0;
  270. for (zi = 0; zi < QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE && !res; zi++) {
  271. if (qnetd_static_supported_decision_algorithms[zi] ==
  272. msg->decision_algorithm) {
  273. res = 1;
  274. }
  275. }
  276. if (!res) {
  277. qnetd_log(LOG_ERR, "Client requested unsupported decision algorithm %u. "
  278. "Sending error reply.", msg->decision_algorithm);
  279. reply_error_code = TLV_REPLY_ERROR_CODE_UNSUPPORTED_DECISION_ALGORITHM;
  280. }
  281. client->decision_algorithm = msg->decision_algorithm;
  282. }
  283. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  284. cluster = qnetd_cluster_list_add_client(&instance->clusters, client);
  285. if (cluster == NULL) {
  286. qnetd_log(LOG_ERR, "Can't add client to cluster list. "
  287. "Sending error reply.");
  288. reply_error_code = TLV_REPLY_ERROR_CODE_INTERNAL_ERROR;
  289. } else {
  290. client->cluster = cluster;
  291. client->cluster_list = &instance->clusters;
  292. }
  293. }
  294. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  295. qnetd_log_debug_new_client_connected(client);
  296. reply_error_code = qnetd_algorithm_client_init(client);
  297. }
  298. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  299. /*
  300. * Correct init received
  301. */
  302. client->init_received = 1;
  303. } else {
  304. qnetd_log(LOG_ERR, "Algorithm returned error code. Sending error reply.");
  305. }
  306. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  307. if (send_buffer == NULL) {
  308. qnetd_log(LOG_ERR, "Can't alloc init reply msg from list. "
  309. "Disconnecting client connection.");
  310. return (-1);
  311. }
  312. if (msg_create_init_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  313. reply_error_code,
  314. supported_msgs, no_supported_msgs, supported_opts, no_supported_opts,
  315. instance->max_client_receive_size, instance->max_client_send_size,
  316. qnetd_static_supported_decision_algorithms,
  317. QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE) == -1) {
  318. qnetd_log(LOG_ERR, "Can't alloc init reply msg. Disconnecting client connection.");
  319. return (-1);
  320. }
  321. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  322. return (0);
  323. }
  324. static int
  325. qnetd_client_msg_received_init_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  326. const struct msg_decoded *msg)
  327. {
  328. return (qnetd_client_msg_received_unexpected_msg(client, msg, "init reply"));
  329. }
  330. static int
  331. qnetd_client_msg_received_set_option_reply(struct qnetd_instance *instance,
  332. struct qnetd_client *client, const struct msg_decoded *msg)
  333. {
  334. return (qnetd_client_msg_received_unexpected_msg(client, msg, "set option reply"));
  335. }
  336. static int
  337. qnetd_client_msg_received_set_option(struct qnetd_instance *instance, struct qnetd_client *client,
  338. const struct msg_decoded *msg)
  339. {
  340. int res;
  341. struct send_buffer_list_entry *send_buffer;
  342. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  343. return (res == -1 ? -1 : 0);
  344. }
  345. if (!client->init_received) {
  346. qnetd_log(LOG_ERR, "Received set option message before init message. "
  347. "Sending error reply.");
  348. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  349. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  350. return (-1);
  351. }
  352. return (0);
  353. }
  354. if (msg->heartbeat_interval_set) {
  355. /*
  356. * Check if heartbeat interval is valid
  357. */
  358. if (msg->heartbeat_interval != 0 &&
  359. (msg->heartbeat_interval < QNETD_HEARTBEAT_INTERVAL_MIN ||
  360. msg->heartbeat_interval > QNETD_HEARTBEAT_INTERVAL_MAX)) {
  361. qnetd_log(LOG_ERR, "Client requested invalid heartbeat interval %u. "
  362. "Sending error reply.", msg->heartbeat_interval);
  363. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  364. TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL) != 0) {
  365. return (-1);
  366. }
  367. return (0);
  368. }
  369. client->heartbeat_interval = msg->heartbeat_interval;
  370. }
  371. if (msg->tie_breaker_set) {
  372. memcpy(&client->tie_breaker, &msg->tie_breaker, sizeof(msg->tie_breaker));
  373. }
  374. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  375. if (send_buffer == NULL) {
  376. qnetd_log(LOG_ERR, "Can't alloc set option reply msg from list. "
  377. "Disconnecting client connection.");
  378. return (-1);
  379. }
  380. if (msg_create_set_option_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  381. client->decision_algorithm, client->heartbeat_interval,
  382. msg->tie_breaker_set, &msg->tie_breaker) == -1) {
  383. qnetd_log(LOG_ERR, "Can't alloc set option reply msg. "
  384. "Disconnecting client connection.");
  385. return (-1);
  386. }
  387. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  388. return (0);
  389. }
  390. static int
  391. qnetd_client_msg_received_echo_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  392. const struct msg_decoded *msg)
  393. {
  394. return (qnetd_client_msg_received_unexpected_msg(client, msg, "echo reply"));
  395. }
  396. static int
  397. qnetd_client_msg_received_echo_request(struct qnetd_instance *instance, struct qnetd_client *client,
  398. const struct msg_decoded *msg, const struct dynar *msg_orig)
  399. {
  400. int res;
  401. struct send_buffer_list_entry *send_buffer;
  402. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  403. return (res == -1 ? -1 : 0);
  404. }
  405. if (!client->init_received) {
  406. qnetd_log(LOG_ERR, "Received echo request before init message. "
  407. "Sending error reply.");
  408. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  409. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  410. return (-1);
  411. }
  412. return (0);
  413. }
  414. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  415. if (send_buffer == NULL) {
  416. qnetd_log(LOG_ERR, "Can't alloc echo reply msg from list. "
  417. "Disconnecting client connection.");
  418. return (-1);
  419. }
  420. if (msg_create_echo_reply(&send_buffer->buffer, msg_orig) == -1) {
  421. qnetd_log(LOG_ERR, "Can't alloc echo reply msg. Disconnecting client connection.");
  422. return (-1);
  423. }
  424. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  425. return (0);
  426. }
  427. static int
  428. qnetd_client_msg_received_node_list(struct qnetd_instance *instance, struct qnetd_client *client,
  429. const struct msg_decoded *msg)
  430. {
  431. int res;
  432. struct send_buffer_list_entry *send_buffer;
  433. enum tlv_reply_error_code reply_error_code;
  434. enum tlv_vote result_vote;
  435. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  436. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  437. return (res == -1 ? -1 : 0);
  438. }
  439. if (!client->init_received) {
  440. qnetd_log(LOG_ERR, "Received node list message before init message. "
  441. "Sending error reply.");
  442. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  443. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  444. return (-1);
  445. }
  446. return (0);
  447. }
  448. if (!msg->node_list_type_set) {
  449. qnetd_log(LOG_ERR, "Received node list message without node list type set. "
  450. "Sending error reply.");
  451. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  452. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  453. return (-1);
  454. }
  455. return (0);
  456. }
  457. if (!msg->seq_number_set) {
  458. qnetd_log(LOG_ERR, "Received node list message without seq number set. "
  459. "Sending error reply.");
  460. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  461. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  462. return (-1);
  463. }
  464. return (0);
  465. }
  466. result_vote = TLV_VOTE_NO_CHANGE;
  467. switch (msg->node_list_type) {
  468. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  469. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  470. qnetd_log_debug_config_node_list_received(client, msg->seq_number,
  471. msg->config_version_set, msg->config_version, &msg->nodes,
  472. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG));
  473. reply_error_code = qnetd_algorithm_config_node_list_received(client,
  474. msg->seq_number, msg->config_version_set, msg->config_version,
  475. &msg->nodes,
  476. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG),
  477. &result_vote);
  478. break;
  479. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  480. if (!msg->ring_id_set) {
  481. qnetd_log(LOG_ERR, "Received node list message without ring id number set. "
  482. "Sending error reply.");
  483. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  484. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  485. return (-1);
  486. }
  487. return (0);
  488. }
  489. /*
  490. * TODO REMOVE THIS memcpy.
  491. */
  492. memcpy(&client->last_ring_id, &msg->ring_id, sizeof(struct tlv_ring_id));
  493. qnetd_log_debug_membership_node_list_received(client, msg->seq_number, &msg->ring_id,
  494. &msg->nodes);
  495. reply_error_code = qnetd_algorithm_membership_node_list_received(client,
  496. msg->seq_number, &msg->ring_id, &msg->nodes, &result_vote);
  497. break;
  498. case TLV_NODE_LIST_TYPE_QUORUM:
  499. if (!msg->quorate_set) {
  500. qnetd_log(LOG_ERR, "Received quorum list message without quorate set. "
  501. "Sending error reply.");
  502. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  503. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  504. return (-1);
  505. }
  506. return (0);
  507. }
  508. qnetd_log_debug_quorum_node_list_received(client, msg->seq_number,msg->quorate,
  509. &msg->nodes);
  510. reply_error_code = qnetd_algorithm_quorum_node_list_received(client,
  511. msg->seq_number,msg->quorate, &msg->nodes, &result_vote);
  512. break;
  513. default:
  514. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  515. "Unhandled node_list_type");
  516. exit(1);
  517. break;
  518. }
  519. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  520. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  521. "Sending error reply.");
  522. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  523. reply_error_code) != 0) {
  524. return (-1);
  525. }
  526. return (0);
  527. } else {
  528. qnetd_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
  529. }
  530. if (msg->node_list_type == TLV_NODE_LIST_TYPE_MEMBERSHIP &&
  531. result_vote == TLV_VOTE_NO_CHANGE) {
  532. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  533. "node_list_type is membership and algorithm result vote is no_change");
  534. exit(1);
  535. }
  536. /*
  537. * Store node list for future use
  538. */
  539. switch (msg->node_list_type) {
  540. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  541. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  542. node_list_free(&client->configuration_node_list);
  543. if (node_list_clone(&client->configuration_node_list, &msg->nodes) == -1) {
  544. qnetd_log(LOG_ERR, "Can't alloc config node list clone. "
  545. "Disconnecting client connection.");
  546. return (-1);
  547. }
  548. break;
  549. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  550. node_list_free(&client->last_membership_node_list);
  551. if (node_list_clone(&client->last_membership_node_list, &msg->nodes) == -1) {
  552. qnetd_log(LOG_ERR, "Can't alloc membership node list clone. "
  553. "Disconnecting client connection.");
  554. return (-1);
  555. }
  556. memcpy(&client->last_ring_id, &msg->ring_id, sizeof(struct tlv_ring_id));
  557. break;
  558. case TLV_NODE_LIST_TYPE_QUORUM:
  559. node_list_free(&client->last_quorum_node_list);
  560. if (node_list_clone(&client->last_quorum_node_list, &msg->nodes) == -1) {
  561. qnetd_log(LOG_ERR, "Can't alloc quorum node list clone. "
  562. "Disconnecting client connection.");
  563. return (-1);
  564. }
  565. break;
  566. default:
  567. qnetd_log(LOG_ERR, "qnetd_client_msg_received_node_list fatal error. "
  568. "Unhandled node_list_type");
  569. exit(1);
  570. break;
  571. }
  572. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  573. if (send_buffer == NULL) {
  574. qnetd_log(LOG_ERR, "Can't alloc node list reply msg from list. "
  575. "Disconnecting client connection.");
  576. return (-1);
  577. }
  578. if (msg_create_node_list_reply(&send_buffer->buffer, msg->seq_number, msg->node_list_type,
  579. msg->ring_id_set, &msg->ring_id, result_vote) == -1) {
  580. qnetd_log(LOG_ERR, "Can't alloc node list reply msg. "
  581. "Disconnecting client connection.");
  582. return (-1);
  583. }
  584. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  585. return (0);
  586. }
  587. static int
  588. qnetd_client_msg_received_node_list_reply(struct qnetd_instance *instance,
  589. struct qnetd_client *client, const struct msg_decoded *msg)
  590. {
  591. return (qnetd_client_msg_received_unexpected_msg(client, msg, "node list reply"));
  592. }
  593. static int
  594. qnetd_client_msg_received_ask_for_vote(struct qnetd_instance *instance, struct qnetd_client *client,
  595. const struct msg_decoded *msg)
  596. {
  597. int res;
  598. struct send_buffer_list_entry *send_buffer;
  599. enum tlv_reply_error_code reply_error_code;
  600. enum tlv_vote result_vote;
  601. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  602. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  603. return (res == -1 ? -1 : 0);
  604. }
  605. if (!client->init_received) {
  606. qnetd_log(LOG_ERR, "Received ask for vote message before init message. "
  607. "Sending error reply.");
  608. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  609. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  610. return (-1);
  611. }
  612. return (0);
  613. }
  614. if (!msg->seq_number_set) {
  615. qnetd_log(LOG_ERR, "Received ask for vote message without seq number set. "
  616. "Sending error reply.");
  617. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  618. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  619. return (-1);
  620. }
  621. return (0);
  622. }
  623. qnetd_log_debug_ask_for_vote_received(client, msg->seq_number);
  624. reply_error_code = qnetd_algorithm_ask_for_vote_received(client, msg->seq_number,
  625. &result_vote);
  626. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  627. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  628. "Sending error reply.");
  629. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  630. reply_error_code) != 0) {
  631. return (-1);
  632. }
  633. return (0);
  634. } else {
  635. qnetd_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
  636. }
  637. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  638. if (send_buffer == NULL) {
  639. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg from list. "
  640. "Disconnecting client connection.");
  641. return (-1);
  642. }
  643. if (msg_create_ask_for_vote_reply(&send_buffer->buffer, msg->seq_number,
  644. result_vote) == -1) {
  645. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg. "
  646. "Disconnecting client connection.");
  647. return (-1);
  648. }
  649. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  650. return (0);
  651. }
  652. static int
  653. qnetd_client_msg_received_ask_for_vote_reply(struct qnetd_instance *instance,
  654. struct qnetd_client *client, const struct msg_decoded *msg)
  655. {
  656. return (qnetd_client_msg_received_unexpected_msg(client, msg, "ask for vote reply"));
  657. }
  658. static int
  659. qnetd_client_msg_received_vote_info(struct qnetd_instance *instance, struct qnetd_client *client,
  660. const struct msg_decoded *msg)
  661. {
  662. return (qnetd_client_msg_received_unexpected_msg(client, msg, "vote info"));
  663. }
  664. static int
  665. qnetd_client_msg_received_vote_info_reply(struct qnetd_instance *instance,
  666. struct qnetd_client *client, const struct msg_decoded *msg)
  667. {
  668. int res;
  669. enum tlv_reply_error_code reply_error_code;
  670. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  671. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  672. return (res == -1 ? -1 : 0);
  673. }
  674. if (!client->init_received) {
  675. qnetd_log(LOG_ERR, "Received vote info reply before init message. "
  676. "Sending error reply.");
  677. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  678. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  679. return (-1);
  680. }
  681. return (0);
  682. }
  683. if (!msg->seq_number_set) {
  684. qnetd_log(LOG_ERR, "Received vote info reply message without seq number set. "
  685. "Sending error reply.");
  686. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  687. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  688. return (-1);
  689. }
  690. return (0);
  691. }
  692. qnetd_log_debug_vote_info_reply_received(client, msg->seq_number);
  693. reply_error_code = qnetd_algorithm_vote_info_reply_received(client, msg->seq_number);
  694. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  695. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  696. "Sending error reply.");
  697. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  698. reply_error_code) != 0) {
  699. return (-1);
  700. }
  701. return (0);
  702. }
  703. return (0);
  704. }
  705. int
  706. qnetd_client_msg_received(struct qnetd_instance *instance, struct qnetd_client *client)
  707. {
  708. struct msg_decoded msg;
  709. int res;
  710. int ret_val;
  711. msg_decoded_init(&msg);
  712. res = msg_decode(&client->receive_buffer, &msg);
  713. if (res != 0) {
  714. /*
  715. * Error occurred. Send server error.
  716. */
  717. qnetd_log_msg_decode_error(res);
  718. qnetd_log(LOG_INFO, "Sending back error message");
  719. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  720. TLV_REPLY_ERROR_CODE_ERROR_DECODING_MSG) != 0) {
  721. return (-1);
  722. }
  723. return (0);
  724. }
  725. ret_val = 0;
  726. switch (msg.type) {
  727. case MSG_TYPE_PREINIT:
  728. ret_val = qnetd_client_msg_received_preinit(instance, client, &msg);
  729. break;
  730. case MSG_TYPE_PREINIT_REPLY:
  731. ret_val = qnetd_client_msg_received_preinit_reply(instance, client, &msg);
  732. break;
  733. case MSG_TYPE_STARTTLS:
  734. ret_val = qnetd_client_msg_received_starttls(instance, client, &msg);
  735. break;
  736. case MSG_TYPE_INIT:
  737. ret_val = qnetd_client_msg_received_init(instance, client, &msg);
  738. break;
  739. case MSG_TYPE_INIT_REPLY:
  740. ret_val = qnetd_client_msg_received_init_reply(instance, client, &msg);
  741. break;
  742. case MSG_TYPE_SERVER_ERROR:
  743. ret_val = qnetd_client_msg_received_server_error(instance, client, &msg);
  744. break;
  745. case MSG_TYPE_SET_OPTION:
  746. ret_val = qnetd_client_msg_received_set_option(instance, client, &msg);
  747. break;
  748. case MSG_TYPE_SET_OPTION_REPLY:
  749. ret_val = qnetd_client_msg_received_set_option_reply(instance, client, &msg);
  750. break;
  751. case MSG_TYPE_ECHO_REQUEST:
  752. ret_val = qnetd_client_msg_received_echo_request(instance, client, &msg,
  753. &client->receive_buffer);
  754. break;
  755. case MSG_TYPE_ECHO_REPLY:
  756. ret_val = qnetd_client_msg_received_echo_reply(instance, client, &msg);
  757. break;
  758. case MSG_TYPE_NODE_LIST:
  759. ret_val = qnetd_client_msg_received_node_list(instance, client, &msg);
  760. break;
  761. case MSG_TYPE_NODE_LIST_REPLY:
  762. ret_val = qnetd_client_msg_received_node_list_reply(instance, client, &msg);
  763. break;
  764. case MSG_TYPE_ASK_FOR_VOTE:
  765. ret_val = qnetd_client_msg_received_ask_for_vote(instance, client, &msg);
  766. break;
  767. case MSG_TYPE_ASK_FOR_VOTE_REPLY:
  768. ret_val = qnetd_client_msg_received_ask_for_vote_reply(instance, client, &msg);
  769. break;
  770. case MSG_TYPE_VOTE_INFO:
  771. ret_val = qnetd_client_msg_received_vote_info(instance, client, &msg);
  772. break;
  773. case MSG_TYPE_VOTE_INFO_REPLY:
  774. ret_val = qnetd_client_msg_received_vote_info_reply(instance, client, &msg);
  775. break;
  776. default:
  777. qnetd_log(LOG_ERR, "Unsupported message %u received from client. "
  778. "Sending back error message", msg.type);
  779. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  780. TLV_REPLY_ERROR_CODE_UNSUPPORTED_MESSAGE) != 0) {
  781. ret_val = -1;
  782. }
  783. break;
  784. }
  785. msg_decoded_destroy(&msg);
  786. return (ret_val);
  787. }