qnetd-client-msg-received.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  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. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  145. return (-1);
  146. };
  147. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  148. return (0);
  149. }
  150. static int
  151. qnetd_client_msg_received_unexpected_msg(struct qnetd_client *client,
  152. const struct msg_decoded *msg, const char *msg_str)
  153. {
  154. qnetd_log(LOG_ERR, "Received %s message. Sending back error message", msg_str);
  155. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  156. TLV_REPLY_ERROR_CODE_UNEXPECTED_MESSAGE) != 0) {
  157. return (-1);
  158. }
  159. return (0);
  160. }
  161. static int
  162. qnetd_client_msg_received_preinit_reply(struct qnetd_instance *instance,
  163. struct qnetd_client *client, const struct msg_decoded *msg)
  164. {
  165. return (qnetd_client_msg_received_unexpected_msg(client, msg, "preinit reply"));
  166. }
  167. static int
  168. qnetd_client_msg_received_starttls(struct qnetd_instance *instance, struct qnetd_client *client,
  169. const struct msg_decoded *msg)
  170. {
  171. PRFileDesc *new_pr_fd;
  172. if (!client->preinit_received) {
  173. qnetd_log(LOG_ERR, "Received starttls before preinit message. "
  174. "Sending error reply.");
  175. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  176. TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED) != 0) {
  177. return (-1);
  178. }
  179. return (0);
  180. }
  181. if ((new_pr_fd = nss_sock_start_ssl_as_server(client->socket, instance->server.cert,
  182. instance->server.private_key, instance->tls_client_cert_required, 0, NULL)) == NULL) {
  183. qnetd_log_nss(LOG_ERR, "Can't start TLS. Disconnecting client.");
  184. return (-1);
  185. }
  186. client->tls_started = 1;
  187. client->tls_peer_certificate_verified = 0;
  188. client->socket = new_pr_fd;
  189. return (0);
  190. }
  191. static int
  192. qnetd_client_msg_received_server_error(struct qnetd_instance *instance, struct qnetd_client *client,
  193. const struct msg_decoded *msg)
  194. {
  195. return (qnetd_client_msg_received_unexpected_msg(client, msg, "server error"));
  196. }
  197. static int
  198. qnetd_client_msg_received_init(struct qnetd_instance *instance, struct qnetd_client *client,
  199. const struct msg_decoded *msg)
  200. {
  201. int res;
  202. size_t zi;
  203. enum msg_type *supported_msgs;
  204. size_t no_supported_msgs;
  205. enum tlv_opt_type *supported_opts;
  206. size_t no_supported_opts;
  207. struct send_buffer_list_entry *send_buffer;
  208. enum tlv_reply_error_code reply_error_code;
  209. struct qnetd_cluster *cluster;
  210. supported_msgs = NULL;
  211. supported_opts = NULL;
  212. no_supported_msgs = 0;
  213. no_supported_opts = 0;
  214. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  215. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  216. return (res == -1 ? -1 : 0);
  217. }
  218. if (!client->preinit_received) {
  219. qnetd_log(LOG_ERR, "Received init before preinit message. Sending error reply.");
  220. reply_error_code = TLV_REPLY_ERROR_CODE_PREINIT_REQUIRED;
  221. }
  222. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->node_id_set) {
  223. qnetd_log(LOG_ERR, "Received init message without node id set. "
  224. "Sending error reply.");
  225. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  226. } else {
  227. client->node_id_set = 1;
  228. client->node_id = msg->node_id;
  229. }
  230. if (msg->supported_messages != NULL) {
  231. /*
  232. * Client sent supported messages. For now this is ignored but in the future
  233. * this may be used to ensure backward compatibility.
  234. */
  235. /*
  236. for (i = 0; i < msg->no_supported_messages; i++) {
  237. qnetd_log(LOG_DEBUG, "Client supports %u message",
  238. (int)msg->supported_messages[i]);
  239. }
  240. */
  241. /*
  242. * Sent back supported messages
  243. */
  244. msg_get_supported_messages(&supported_msgs, &no_supported_msgs);
  245. }
  246. if (msg->supported_options != NULL) {
  247. /*
  248. * Client sent supported options. For now this is ignored but in the future
  249. * this may be used to ensure backward compatibility.
  250. */
  251. /*
  252. for (i = 0; i < msg->no_supported_options; i++) {
  253. qnetd_log(LOG_DEBUG, "Client supports %u option",
  254. (int)msg->supported_messages[i]);
  255. }
  256. */
  257. /*
  258. * Send back supported options
  259. */
  260. tlv_get_supported_options(&supported_opts, &no_supported_opts);
  261. }
  262. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->decision_algorithm_set) {
  263. qnetd_log(LOG_ERR, "Received init message without decision algorithm. "
  264. "Sending error reply.");
  265. reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
  266. } else {
  267. /*
  268. * Check if decision algorithm requested by client is supported
  269. */
  270. res = 0;
  271. for (zi = 0; zi < QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE && !res; zi++) {
  272. if (qnetd_static_supported_decision_algorithms[zi] ==
  273. msg->decision_algorithm) {
  274. res = 1;
  275. }
  276. }
  277. if (!res) {
  278. qnetd_log(LOG_ERR, "Client requested unsupported decision algorithm %u. "
  279. "Sending error reply.", msg->decision_algorithm);
  280. reply_error_code = TLV_REPLY_ERROR_CODE_UNSUPPORTED_DECISION_ALGORITHM;
  281. }
  282. client->decision_algorithm = msg->decision_algorithm;
  283. }
  284. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  285. cluster = qnetd_cluster_list_add_client(&instance->clusters, client);
  286. if (cluster == NULL) {
  287. qnetd_log(LOG_ERR, "Can't add client to cluster list. "
  288. "Sending error reply.");
  289. reply_error_code = TLV_REPLY_ERROR_CODE_INTERNAL_ERROR;
  290. } else {
  291. client->cluster = cluster;
  292. client->cluster_list = &instance->clusters;
  293. }
  294. }
  295. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  296. qnetd_log_debug_new_client_connected(client);
  297. reply_error_code = qnetd_algorithm_client_init(client);
  298. }
  299. if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR) {
  300. /*
  301. * Correct init received
  302. */
  303. client->init_received = 1;
  304. } else {
  305. qnetd_log(LOG_ERR, "Algorithm returned error code. Sending error reply.");
  306. }
  307. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  308. if (send_buffer == NULL) {
  309. qnetd_log(LOG_ERR, "Can't alloc init reply msg from list. "
  310. "Disconnecting client connection.");
  311. return (-1);
  312. }
  313. if (msg_create_init_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  314. reply_error_code,
  315. supported_msgs, no_supported_msgs, supported_opts, no_supported_opts,
  316. instance->max_client_receive_size, instance->max_client_send_size,
  317. qnetd_static_supported_decision_algorithms,
  318. QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE) == -1) {
  319. qnetd_log(LOG_ERR, "Can't alloc init reply msg. Disconnecting client connection.");
  320. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  321. return (-1);
  322. }
  323. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  324. return (0);
  325. }
  326. static int
  327. qnetd_client_msg_received_init_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  328. const struct msg_decoded *msg)
  329. {
  330. return (qnetd_client_msg_received_unexpected_msg(client, msg, "init reply"));
  331. }
  332. static int
  333. qnetd_client_msg_received_set_option_reply(struct qnetd_instance *instance,
  334. struct qnetd_client *client, const struct msg_decoded *msg)
  335. {
  336. return (qnetd_client_msg_received_unexpected_msg(client, msg, "set option reply"));
  337. }
  338. static int
  339. qnetd_client_msg_received_set_option(struct qnetd_instance *instance, struct qnetd_client *client,
  340. const struct msg_decoded *msg)
  341. {
  342. int res;
  343. struct send_buffer_list_entry *send_buffer;
  344. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  345. return (res == -1 ? -1 : 0);
  346. }
  347. if (!client->init_received) {
  348. qnetd_log(LOG_ERR, "Received set option message before init message. "
  349. "Sending error reply.");
  350. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  351. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  352. return (-1);
  353. }
  354. return (0);
  355. }
  356. if (msg->heartbeat_interval_set) {
  357. /*
  358. * Check if heartbeat interval is valid
  359. */
  360. if (msg->heartbeat_interval != 0 &&
  361. (msg->heartbeat_interval < QNETD_HEARTBEAT_INTERVAL_MIN ||
  362. msg->heartbeat_interval > QNETD_HEARTBEAT_INTERVAL_MAX)) {
  363. qnetd_log(LOG_ERR, "Client requested invalid heartbeat interval %u. "
  364. "Sending error reply.", msg->heartbeat_interval);
  365. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  366. TLV_REPLY_ERROR_CODE_INVALID_HEARTBEAT_INTERVAL) != 0) {
  367. return (-1);
  368. }
  369. return (0);
  370. }
  371. client->heartbeat_interval = msg->heartbeat_interval;
  372. }
  373. if (msg->tie_breaker_set) {
  374. memcpy(&client->tie_breaker, &msg->tie_breaker, sizeof(msg->tie_breaker));
  375. }
  376. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  377. if (send_buffer == NULL) {
  378. qnetd_log(LOG_ERR, "Can't alloc set option reply msg from list. "
  379. "Disconnecting client connection.");
  380. return (-1);
  381. }
  382. if (msg_create_set_option_reply(&send_buffer->buffer, msg->seq_number_set, msg->seq_number,
  383. client->decision_algorithm, client->heartbeat_interval,
  384. msg->tie_breaker_set, &msg->tie_breaker) == -1) {
  385. qnetd_log(LOG_ERR, "Can't alloc set option reply msg. "
  386. "Disconnecting client connection.");
  387. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  388. return (-1);
  389. }
  390. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  391. return (0);
  392. }
  393. static int
  394. qnetd_client_msg_received_echo_reply(struct qnetd_instance *instance, struct qnetd_client *client,
  395. const struct msg_decoded *msg)
  396. {
  397. return (qnetd_client_msg_received_unexpected_msg(client, msg, "echo reply"));
  398. }
  399. static int
  400. qnetd_client_msg_received_echo_request(struct qnetd_instance *instance, struct qnetd_client *client,
  401. const struct msg_decoded *msg, const struct dynar *msg_orig)
  402. {
  403. int res;
  404. struct send_buffer_list_entry *send_buffer;
  405. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  406. return (res == -1 ? -1 : 0);
  407. }
  408. if (!client->init_received) {
  409. qnetd_log(LOG_ERR, "Received echo request before init message. "
  410. "Sending error reply.");
  411. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  412. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  413. return (-1);
  414. }
  415. return (0);
  416. }
  417. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  418. if (send_buffer == NULL) {
  419. qnetd_log(LOG_ERR, "Can't alloc echo reply msg from list. "
  420. "Disconnecting client connection.");
  421. return (-1);
  422. }
  423. if (msg_create_echo_reply(&send_buffer->buffer, msg_orig) == -1) {
  424. qnetd_log(LOG_ERR, "Can't alloc echo reply msg. Disconnecting client connection.");
  425. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  426. return (-1);
  427. }
  428. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  429. return (0);
  430. }
  431. static int
  432. qnetd_client_msg_received_node_list(struct qnetd_instance *instance, struct qnetd_client *client,
  433. const struct msg_decoded *msg)
  434. {
  435. int res;
  436. struct send_buffer_list_entry *send_buffer;
  437. enum tlv_reply_error_code reply_error_code;
  438. enum tlv_vote result_vote;
  439. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  440. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  441. return (res == -1 ? -1 : 0);
  442. }
  443. if (!client->init_received) {
  444. qnetd_log(LOG_ERR, "Received node list message before init message. "
  445. "Sending error reply.");
  446. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  447. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  448. return (-1);
  449. }
  450. return (0);
  451. }
  452. if (!msg->node_list_type_set) {
  453. qnetd_log(LOG_ERR, "Received node list message without node list type set. "
  454. "Sending error reply.");
  455. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  456. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  457. return (-1);
  458. }
  459. return (0);
  460. }
  461. if (!msg->seq_number_set) {
  462. qnetd_log(LOG_ERR, "Received node list message without seq number set. "
  463. "Sending error reply.");
  464. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  465. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  466. return (-1);
  467. }
  468. return (0);
  469. }
  470. result_vote = TLV_VOTE_NO_CHANGE;
  471. switch (msg->node_list_type) {
  472. case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
  473. case TLV_NODE_LIST_TYPE_CHANGED_CONFIG:
  474. qnetd_log_debug_config_node_list_received(client, msg->seq_number,
  475. msg->config_version_set, msg->config_version, &msg->nodes,
  476. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG));
  477. reply_error_code = qnetd_algorithm_config_node_list_received(client,
  478. msg->seq_number, msg->config_version_set, msg->config_version,
  479. &msg->nodes,
  480. (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG),
  481. &result_vote);
  482. break;
  483. case TLV_NODE_LIST_TYPE_MEMBERSHIP:
  484. if (!msg->ring_id_set) {
  485. qnetd_log(LOG_ERR, "Received node list message without ring id number set. "
  486. "Sending error reply.");
  487. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  488. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  489. return (-1);
  490. }
  491. return (0);
  492. }
  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. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  583. return (-1);
  584. }
  585. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  586. return (0);
  587. }
  588. static int
  589. qnetd_client_msg_received_node_list_reply(struct qnetd_instance *instance,
  590. struct qnetd_client *client, const struct msg_decoded *msg)
  591. {
  592. return (qnetd_client_msg_received_unexpected_msg(client, msg, "node list reply"));
  593. }
  594. static int
  595. qnetd_client_msg_received_ask_for_vote(struct qnetd_instance *instance, struct qnetd_client *client,
  596. const struct msg_decoded *msg)
  597. {
  598. int res;
  599. struct send_buffer_list_entry *send_buffer;
  600. enum tlv_reply_error_code reply_error_code;
  601. enum tlv_vote result_vote;
  602. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  603. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  604. return (res == -1 ? -1 : 0);
  605. }
  606. if (!client->init_received) {
  607. qnetd_log(LOG_ERR, "Received ask for vote message before init message. "
  608. "Sending error reply.");
  609. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  610. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  611. return (-1);
  612. }
  613. return (0);
  614. }
  615. if (!msg->seq_number_set) {
  616. qnetd_log(LOG_ERR, "Received ask for vote message without seq number set. "
  617. "Sending error reply.");
  618. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  619. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  620. return (-1);
  621. }
  622. return (0);
  623. }
  624. qnetd_log_debug_ask_for_vote_received(client, msg->seq_number);
  625. reply_error_code = qnetd_algorithm_ask_for_vote_received(client, msg->seq_number,
  626. &result_vote);
  627. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  628. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  629. "Sending error reply.");
  630. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  631. reply_error_code) != 0) {
  632. return (-1);
  633. }
  634. return (0);
  635. } else {
  636. qnetd_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
  637. }
  638. send_buffer = send_buffer_list_get_new(&client->send_buffer_list);
  639. if (send_buffer == NULL) {
  640. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg from list. "
  641. "Disconnecting client connection.");
  642. return (-1);
  643. }
  644. if (msg_create_ask_for_vote_reply(&send_buffer->buffer, msg->seq_number,
  645. result_vote) == -1) {
  646. qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg. "
  647. "Disconnecting client connection.");
  648. send_buffer_list_discard_new(&client->send_buffer_list, send_buffer);
  649. return (-1);
  650. }
  651. send_buffer_list_put(&client->send_buffer_list, send_buffer);
  652. return (0);
  653. }
  654. static int
  655. qnetd_client_msg_received_ask_for_vote_reply(struct qnetd_instance *instance,
  656. struct qnetd_client *client, const struct msg_decoded *msg)
  657. {
  658. return (qnetd_client_msg_received_unexpected_msg(client, msg, "ask for vote reply"));
  659. }
  660. static int
  661. qnetd_client_msg_received_vote_info(struct qnetd_instance *instance, struct qnetd_client *client,
  662. const struct msg_decoded *msg)
  663. {
  664. return (qnetd_client_msg_received_unexpected_msg(client, msg, "vote info"));
  665. }
  666. static int
  667. qnetd_client_msg_received_vote_info_reply(struct qnetd_instance *instance,
  668. struct qnetd_client *client, const struct msg_decoded *msg)
  669. {
  670. int res;
  671. enum tlv_reply_error_code reply_error_code;
  672. reply_error_code = TLV_REPLY_ERROR_CODE_NO_ERROR;
  673. if ((res = qnetd_client_msg_received_check_tls(instance, client, msg)) != 0) {
  674. return (res == -1 ? -1 : 0);
  675. }
  676. if (!client->init_received) {
  677. qnetd_log(LOG_ERR, "Received vote info reply before init message. "
  678. "Sending error reply.");
  679. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  680. TLV_REPLY_ERROR_CODE_INIT_REQUIRED) != 0) {
  681. return (-1);
  682. }
  683. return (0);
  684. }
  685. if (!msg->seq_number_set) {
  686. qnetd_log(LOG_ERR, "Received vote info reply message without seq number set. "
  687. "Sending error reply.");
  688. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  689. TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION) != 0) {
  690. return (-1);
  691. }
  692. return (0);
  693. }
  694. qnetd_log_debug_vote_info_reply_received(client, msg->seq_number);
  695. reply_error_code = qnetd_algorithm_vote_info_reply_received(client, msg->seq_number);
  696. if (reply_error_code != TLV_REPLY_ERROR_CODE_NO_ERROR) {
  697. qnetd_log(LOG_ERR, "Algorithm returned error code. "
  698. "Sending error reply.");
  699. if (qnetd_client_send_err(client, msg->seq_number_set, msg->seq_number,
  700. reply_error_code) != 0) {
  701. return (-1);
  702. }
  703. return (0);
  704. }
  705. return (0);
  706. }
  707. int
  708. qnetd_client_msg_received(struct qnetd_instance *instance, struct qnetd_client *client)
  709. {
  710. struct msg_decoded msg;
  711. int res;
  712. int ret_val;
  713. msg_decoded_init(&msg);
  714. res = msg_decode(&client->receive_buffer, &msg);
  715. if (res != 0) {
  716. /*
  717. * Error occurred. Send server error.
  718. */
  719. qnetd_log_msg_decode_error(res);
  720. qnetd_log(LOG_INFO, "Sending back error message");
  721. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  722. TLV_REPLY_ERROR_CODE_ERROR_DECODING_MSG) != 0) {
  723. return (-1);
  724. }
  725. return (0);
  726. }
  727. ret_val = 0;
  728. switch (msg.type) {
  729. case MSG_TYPE_PREINIT:
  730. ret_val = qnetd_client_msg_received_preinit(instance, client, &msg);
  731. break;
  732. case MSG_TYPE_PREINIT_REPLY:
  733. ret_val = qnetd_client_msg_received_preinit_reply(instance, client, &msg);
  734. break;
  735. case MSG_TYPE_STARTTLS:
  736. ret_val = qnetd_client_msg_received_starttls(instance, client, &msg);
  737. break;
  738. case MSG_TYPE_INIT:
  739. ret_val = qnetd_client_msg_received_init(instance, client, &msg);
  740. break;
  741. case MSG_TYPE_INIT_REPLY:
  742. ret_val = qnetd_client_msg_received_init_reply(instance, client, &msg);
  743. break;
  744. case MSG_TYPE_SERVER_ERROR:
  745. ret_val = qnetd_client_msg_received_server_error(instance, client, &msg);
  746. break;
  747. case MSG_TYPE_SET_OPTION:
  748. ret_val = qnetd_client_msg_received_set_option(instance, client, &msg);
  749. break;
  750. case MSG_TYPE_SET_OPTION_REPLY:
  751. ret_val = qnetd_client_msg_received_set_option_reply(instance, client, &msg);
  752. break;
  753. case MSG_TYPE_ECHO_REQUEST:
  754. ret_val = qnetd_client_msg_received_echo_request(instance, client, &msg,
  755. &client->receive_buffer);
  756. break;
  757. case MSG_TYPE_ECHO_REPLY:
  758. ret_val = qnetd_client_msg_received_echo_reply(instance, client, &msg);
  759. break;
  760. case MSG_TYPE_NODE_LIST:
  761. ret_val = qnetd_client_msg_received_node_list(instance, client, &msg);
  762. break;
  763. case MSG_TYPE_NODE_LIST_REPLY:
  764. ret_val = qnetd_client_msg_received_node_list_reply(instance, client, &msg);
  765. break;
  766. case MSG_TYPE_ASK_FOR_VOTE:
  767. ret_val = qnetd_client_msg_received_ask_for_vote(instance, client, &msg);
  768. break;
  769. case MSG_TYPE_ASK_FOR_VOTE_REPLY:
  770. ret_val = qnetd_client_msg_received_ask_for_vote_reply(instance, client, &msg);
  771. break;
  772. case MSG_TYPE_VOTE_INFO:
  773. ret_val = qnetd_client_msg_received_vote_info(instance, client, &msg);
  774. break;
  775. case MSG_TYPE_VOTE_INFO_REPLY:
  776. ret_val = qnetd_client_msg_received_vote_info_reply(instance, client, &msg);
  777. break;
  778. default:
  779. qnetd_log(LOG_ERR, "Unsupported message %u received from client. "
  780. "Sending back error message", msg.type);
  781. if (qnetd_client_send_err(client, msg.seq_number_set, msg.seq_number,
  782. TLV_REPLY_ERROR_CODE_UNSUPPORTED_MESSAGE) != 0) {
  783. ret_val = -1;
  784. }
  785. break;
  786. }
  787. msg_decoded_destroy(&msg);
  788. return (ret_val);
  789. }